Openfoamtut 1
Openfoamtut 1
Revision 1-2020
JG
                           Acknowledgements
This training material and tutorials are based upon personal experience, OpenFOAM® source
code, OpenFOAM® user guide, OpenFOAM® programmer’s guide, and presentations from
previous OpenFOAM® training sessions and OpenFOAM® workshops.
We gratefully acknowledge the following OpenFOAM® users for sharing online their material or for
giving us their consent to use their material:
     •   Edoardo Alinovi.
     •   Matteo Bargiacchi.
     •   Mattia Cavaiola.
     •   Peyman Davvalo Khongar.
     •   Sehrish Naqvi.
     •   Damiano Natali.
     •   Stefano Olivieri.
     •   Biniyam Sishah.
     •   Giuseppe Zampogna.
                        On the training material
    The following typographical conventions are used in this
                        training material
•   Text in Courier new font indicates Linux commands that should be typed literally by the user
    in the terminal.
•   Text in Courier new bold font indicates directories.
•   Text in Courier new italic font indicates human readable files or ascii files.
•   Text in Arial bold font indicates program elements such as variables, function names, classes,
    statements and so on. It also indicate environment variables, and keywords. They also
    highlight important information.
•   Text in Arial underline in blue font indicates URLs and email addresses.
•   This icon      indicates a warning or a caution.
•   This icon      indicates a tip, suggestion, or a general note.
•   This icon      indicates a folder or directory.
•   This icon      indicates a human readable file (ascii file).
•   This icon      indicates that the figure is an animation (animated gif).
•   These characters $> indicate that a Linux command should be typed literally by the user in the
    terminal.
                   On the training material
The following typographical conventions are used in this
                    training material
• Large code listing, ascii files listing, and screen outputs can be written in
  a square box, as follows:
  1    #include <iostream>
  2    using namespace std;
  3
  4    // main() is where program execution begins. It is the main function.
  5    // Every program in c++ must have this main function declared
  6
  7    int main ()
  8    {
  9         cout << "Hello world";                //prints Hello world
  10        return 0;                             //returns nothing
  11   }
•   To uncompress the tutorials go to the directory where you copied the training material and then type in the
    terminal,
           • $> tar –zxvf file_name.tar.gz
•   In every single tutorial, you will find the file README.FIRST. In this file you will find the general instructions of
    how to run the case. You will also find some additional comments.
•   In some cases, you will also find additional files with the extension .sh. These files can be used to run the
    case automatically, but we highly recommend to open the README.FIRST file and type the commands in the
    terminal, in this way you will get used with the command line interface and OpenFOAM® commands.
•   If you are already comfortable with OpenFOAM®, use the automatic scripts to run the cases.
•   You will find the automatic scripts in the cases explained in the lectures notes and some random cases.
•   A word of caution, use the tutorials included in the training material just for recreational, instructional,
    or learning purposes and not for validation, benchmarking or as standard practices.
                    On the training material
                                  Exercises
• At the end of each section, you will find an exercise section.
• The exercise section is optional, self-paced, and do it at anytime.
• The proposed exercises are designed to test your knowledge and to
  reinforce the concepts addressed during the lectures.
• All the concepts to be addressed in the exercise sections have been treated
  in the lecture notes, so the reader should not have problems answering the
  questions.
• If you have doubts, do not hesitate in asking.
• To help you answering the exercises, we might give you a few tips.
• And if it is necessary, the solution will be given.
                            Housekeeping issues
•   What OpenFOAM® version are we going to use?
     •   During this training we are going to use OpenFOAM® version 8.
     •   The one developed by OpenCFD Ltd (http://www.openfoam.org/).
Week 2.
•   Solid modeling using Onshape, mesh generation, mesh quality assessment, qualitative and quantitative
    postprocessing, scientific visualization
Week 3.
•   Introduction to the finite volume method, numerical playground, best standard practices in CFD and
    OpenFOAM®, implementing boundary conditions and initial conditions using codeStream
Week 4.
•   Implementing boundary conditions and initial conditions using codeStream (continuation), advanced physical
    models (turbulence, multiphase, compressible flows, dynamic meshes, source terms).
Week 5.
•   Advanced physical models (continuation), extra topics (supplements), tips and tricks, closing remarks
                                   Training agenda
Week 1.
•   Module 0, Module 1, Module 4
Week 2.
•   Module 2, Module 3, Module 5
Week 3.
•   Module 6, Module 7
Week 4.
•   Module 7, Module 8
Week 5.
•   Module 8, extra topics
                                   Training agenda
• The training agenda is organized in such a way that we will address the whole CFD simulation workflow.
          Module 1
OpenFOAM® overview – First tutorial –
  Working our way in OpenFOAM®
                                        1
                       Roadmap
                                                           2
               OpenFOAM® brief overview
General description:
• OpenFOAM® stands for Open Source Field Operation and Manipulation.
• OpenFOAM® is first and foremost a C++ library used to solve partial
  differential equations (PDEs), and ordinary differential equations (ODEs).
• It comes with several ready-to-use or out-of-the-box solvers, pre-processing
  utilities, and post-processing utilities.
• It is licensed under the GNU General Public License (GPL). That means it is
  freely available and distributed with the source code.
• It can be used in massively parallel computers. No need to pay for separate
  licenses.
• It is under active development.
• It counts with a wide-spread community around the world (industry,
  academia and research labs).
                                                                                 3
               OpenFOAM® brief overview
Multi-physics simulation capabilities:
• OpenFOAM® has extensive multi-physics simulation capabilities, among
  others:
   • Computational fluid dynamics (incompressible and compressible flows).
   • Computational heat transfer and conjugate heat transfer.
   • Combustion and chemical reactions.
   • Multiphase flows and mass transfer.
   • Particle methods (DEM, DSMC, MD) and lagrangian particles tracking.
   • Stress analysis and fluid-structure interaction.
   • Rotating frames of reference, arbitrary mesh interface, dynamic mesh
     handling, and adaptive mesh refinement.
   • 6 DOF solvers, ODE solvers, computational aero-acoustics,
     computational electromagnetics, computational solid mechanics, MHD.
                                                                             4
              OpenFOAM® brief overview
Physical modeling library:
• OpenFOAM® comes with many physical models, among others:
   • Extensive turbulence modeling capabilities (RANS, DES and LES).
   • Transport/rheology models. Newtonian and non-Newtonian viscosity
     models.
   • Thermophysical models and physical properties for liquids and gases.
   • Source terms models.
   • Lagrangian particle models.
   • Interphase momentum transfer models for multiphase flows.
   • Combustion, flame speed, chemical reactions, porous media, radiation,
     phase change.
                                                                             5
               OpenFOAM® brief overview
Under the hood you will find the following:
• Finite Volume Method (FVM) based solver.
• Collocated polyhedral unstructured meshes.
• Second order accuracy in space and time. Many discretization schemes
  available (including high order methods).
• Steady and transient solvers available.
• Pressure-velocity coupling via segregated methods (SIMPLE and PISO).
• But coupled solvers are under active development.
• Massive parallelism through domain decomposition.
• It comes with its own mesh generation tools.
• It also comes with many mesh manipulation and conversion utilities.
• It comes with many post-processing utilities.
• All components implemented in library form for easy re-use.
                                                                         6
                   OpenFOAM® brief overview
OpenFOAM® vs. Commercial CFD applications:
•   OpenFOAM® capabilities mirror those of commercial CFD applications.
•   The main differences with commercial CFD applications are:
     •   There is no native GUI.
     •   It does not come with predefined setups. The users need to have a basic
         understanding of the CFD basics and be familiar with OpenFOAM® command
         line interface (CLI).
     •   Knowing your way around the Linux bash shell is extremely useful.
     •   It is not a single executable. Depending of what you are looking for, you will
         need to execute a specific application from the CLI.
     •   It is not well documented, but the source code is available.
     •   Access to complete source = no black magic. But to understand the source
         code you need to know object-oriented programming and C++.
     •   Solvers can be tailored for a specific need, therefore OpenFOAM® is ideal for
         research and development.
     •   It is free and has no limitation on the number of cores you can use.
                                                                                          7
                OpenFOAM® brief overview
Developing new solvers (in case you need it):
• As the user has complete access to the source code, she/he has total
  freedom to modify existing solvers or use them as the starting point for new
  solvers.
• New solvers can be easily implemented using OpenFOAM® high level
  programming, e.g.:
                                                              solve
                                                              (
                                                                   fvm::ddt(T)
                                                                 + fvm::div(phi,T)
                                                                 - fvm::laplacian(nu,T)
                                                                   ==
                                                                   0
                                                              );
                                                                                          8
       OpenFOAM® brief overview
                                              9
                       Roadmap
                                                           10
      OpenFOAM® directory organization
$WM_PROJECT_DIR    If you installed OpenFOAM® in the default location, the
├── Allwmake       environment variable $WM_PROJECT_DIR should point
├── applications   to the following directory (depending on the installed
                   version):
├── bin
├── COPYING
├── doc                 $HOME/OpenFOAM/OpenFOAM-8
├── etc                                           or
├── platforms           $HOME/OpenFOAM/OpenFOAM-dev
├── README.org
├── src            In this directory you will find all the files containing
├── tutorials      OpenFOAM® installation.
└── wmake
                   In this directory you will also find additional files (such as
                   README.org, COPYING, etc.), but the most important
                   one is Allwmake, which compiles OpenFOAM®.
                                                                                    11
      OpenFOAM® directory organization
$WM_PROJECT_DIR             OpenFOAM® environment variables
├── Allwmake
├── applications   The entries starting with the symbol $ are environment
├── bin            variables. You can find out the value of an environment
├── COPYING        variable by echoing its value, for example:
├── doc                 $> echo $WM_PROJECT_DIR
├── etc
├── platforms
                   will print out the following information on the terminal,
├── README.org
                        $HOME/OpenFOAM/OpenFOAM-8
├── src
├── tutorials
└── wmake          To list all the environment variables type in the terminal
                   window,
                         $> env
                                                                      14
        OpenFOAM® directory organization
                        The applications directory
                       $WM_PROJECT_DIR/applications
                       ├── Allwmake
                       ├── solvers
                       ├── test
                       └── utilities
                                                                                            15
             OpenFOAM® directory organization
                                     The bin directory
$WM_PROJECT_DIR/bin/                          Let us visit the bin directory:
├── foamCleanPolyMesh
                                              •   The bin directory contains many shell
├── foamCleanTutorials                            scripts, such as foamNew, foamLog,
├── foamCloneCase                                 foamJob, foamNewApp, etc.
├── foamJob
├── foamLog                                   •   This directory also contains the script
                                                  paraFoam that will launch paraView.
├── foamMonitor
├── foamNew
├── foamNewApp
├── foamNewBC
├── foamNewFunctionObject
├── paraFoam
├── ...
└── tools
                                                                              17
      OpenFOAM® directory organization
                       The etc directory
$WM_PROJECT_DIR/etc/         Let us visit the etc directory:
├── bashrc
                             •   The etc directory contains the environment
├── caseDicts
                                 files, global OpenFOAM® instructions,
├── cellModels                   templates, and the default thermochemical
├── codeTemplates                database thermoData/thermoData
├── config.csh
                             •   In the directory caseDicts, you will find many
├── config.sh
                                 templates related to the input files used to setup
├── controlDict                  a case in OpenFOAM®. We recommend you
├── cshrc                        take some time and explore these files.
├── paraFoam
├── README.org               •   It also contains the super dictionary
                                 controlDict, where you can set several
├── templates                    debug flags and the defaults units.
└── thermoData
                                                                                      18
         OpenFOAM® directory organization
                            The platforms directory
                 $WM_PROJECT_DIR/platforms/
                 ├── linux64GccDPInt32Opt
                 │   ├── applications
                 │   ├── bin
                 │   ├── lib
                 │   └── src
                 └── linux64GccDPInt32OptSYSTEMOPENMPI
                     └── src
•   If you want to locate a file inside $WM_PROJECT_DIR that contains the string fvPatch in its
    name, you can proceed as follows,
      •   $> find $WM_PROJECT_DIR –type f -name “*fvPatch*”
•   If you want to find a string inside a file, you can use the grep command.
•   For example, if you want to find the string LES inside all the files within the directory
    $FOAM_SOLVERS, you can proceed as follows,
      •   $> grep -r -n “LES” $FOAM_SOLVERS
          The argument -r means recursive and -n will output the line number.
                                                                                                   25
            OpenFOAM® directory organization
          Looking for information in OpenFOAM® source code
•   Dictionaries are input files required by OpenFOAM®.
•   As you can imagine, there are many dictionaries in OpenFOAM®. The easiest way to find all of
    them is to do a local search in the installation directory as follows,
•   For instance, if you are interested in finding all the files that end with the Dict word in the
    tutorials directory, in the terminal type:
      •   $> find $FOAM_TUTORIALS -name “*Dict”
          (Case sensitive search)
      •   $> find $FOAM_TUTORIALS –iname ‘*dict’
          (Non-case sensitive search)
• When given the search string, you can use single quotes ‘ ’ or double-quotes “ ” (do not mixed
  them).
• We recommend to use single quotes, but it is up to you.
                                                                                                      26
               OpenFOAM® directory organization
         Looking for information in OpenFOAM® source code
•   A few more advanced commands to find information in your OpenFOAM® installation.
     •   To find which tutorial files use the boundary condition slip:
           •   $> find $FOAM_TUTORIALS -type f | xargs grep -sl ‘ slip’
               This command will look for all files inside the directory $FOAM_TUTORIALS, then the
               output is used by grep to search for the string slip.
     •   To find where the source code for the boundary condition slip is located:
           •   $> find $FOAM_SRC -name “*slip*”
                                                                                                     27
              OpenFOAM® directory organization
                                Environment variables
•   Remember, OpenFOAM® uses its own environment variables.
•   OpenFOAM® environment settings are contained in the OpenFOAM-8/etc directory.
•   If you installed OpenFOAM® in the default location, they should be in:
          •   $HOME/OpenFOAM/OpenFOAM-8/etc
•   If you are running bash or ksh (if in doubt type in the terminal echo $SHELL), you sourced the
    $WM_PROJECT_DIR/etc/bashrc file by adding the following line to your $HOME/.bashrc
    file:
          •   source $HOME/OpenFOAM/OpenFOAM-8/etc/bashrc
                                                                                                     28
                       Roadmap
                                                           29
    Directory structure of an OpenFOAM® application/utility
                                                                                32
                       Roadmap
                                                           33
         Applications/utilities in OpenFOAM®
• OpenFOAM® is not a single executable.
• Depending of what you want to do, you will need to use a specific application and
  there are many of them.
• If you are interested in knowing all the solvers, utilities, and libraries that come with
  your OpenFOAM® distribution, read the applications and libraries section in the user
  guide (chapter 3).
• In the directory $WM_PROJECT_DIR/doc you will find the documentation in pdf
  format.
• You can also access the online user guide. Go to the link
  http://cfd.direct/openfoam/user-guide/#contents, then go to chapter 3 (applications
  and libraries).
• If you want to get help on how to run an application, type in terminal
• The option –help will not run the application; it will only show all the options
  available.
• You can also get all the help you want from the source code.                                34
         Applications/utilities in OpenFOAM®
• You will find all the applications in the directory $FOAM_SOLVERS (you can use the
  alias sol to go there).
• You will find all the utilities in the directory $FOAM_UTILITIES (you can use the alias
  util to go there).
• For example, in the directory $FOAM_SOLVERS, you will find the directories containing
  the source code for the solvers available in the OpenFOAM® installation (version 8):
         • basic                                        • financial
         • combustion                                   • heatTransfer
         • compressible                                 • incompressible
         • discreteMethods                              • lagrangian
         • DNS                                          • multiphase
         • electromagnetics                             • stressAnalysis
    • adjointShapeOptimizationFoam                • pimpleFoam
    • boundaryFoam                                • pisoFoam
    • icoFoam                                     • shallowWaterFoam
    • nonNewtonianIcoFoam                         • simpleFoam
• Inside each directory, you will find a file with the extension *.C and the same name
  as the directory. This is the main file, where you will find the top-level source code
  and a short description of the solver or utility.
• For example, in the file incompressible/icoFoam/icoFoam.C you will find the
  following description:
                                                                                           36
          Applications/utilities in OpenFOAM®
•   Remember, OpenFOAM® is not a single executable.
•   You will need to find the solver or utility that best fit what you want to do.
•   A few solvers that we will use during this course:
     •   icoFoam: laminar incompressible unsteady solver. Be careful, do not use this
         solver for production runs as it has many limitations.
     •   simpleFoam: incompressible steady solver for laminar/turbulent flows.
     •   pimpleFoam: incompressible unsteady solver for laminar/turbulent flows.
     •   rhoSimpleFoam: compressible steady solver for laminar/turbulent flows.
     •   rhoPimpleFoam: unsteady compressible solver for (laminar/turbulent flows.
     •   interFoam: unsteady multiphase solver for separated flows using the VOF
         method (laminar and turbulent flows).
     •   laplacianFoam: Laplace equation solver.
     •   potentialFoam: potential flow solver.
     •   scalarTransportFoam: steady/unsteady general transport equation solver.
                                                                                        37
         Applications/utilities in OpenFOAM®
•   Take your time and explore the source code.
•   Also, while exploring the source code be careful not to add unwanted modifications in
    the original installation.
•   If you modify the source code, be sure to do the modifications in your user directory
    instead of the main source code.
                                                                                            38
                       Roadmap
                                                           39
  Directory structure of an OpenFOAM® case
              Directory structure of a general case
case_name                     •   OpenFOAM® uses a very particular directory
├── 0                             structure for running cases.
│   ├── p                     •   You should always follow the directory structure,
│   └── U                         otherwise, OpenFOAM® will complain.
├── constant                  •   To keep everything in order, the case directory is
│   ├── polyMesh                  often located in the path
                                  $WM_PROJECT_USER_DIR/run.
│   │   ├── boundary
│   │   ├── faces             •   This is not compulsory but highly advisable. You can
                                  copy the case files anywhere you want.
│   │   ├── neighbour
                              •   The name of the case directory is given by the user
│   │   ├── owner                 (do not use white spaces or strange symbols).
│   │   └── points
                              •   Depending of the solver or application you would like
│   └── transportProperties       to use, you will need different files in each sub-
├── system                        directory.
│    ├── controlDict          •   Remember, you always run the applications and
│    ├── fvSchemes                utilities in the top level of the case directory (the
│    └── fvSolution               directory with the name case_name). Not in the
                                  directory system, not in the directory constant, not
└── time_directories              in the directory 0.
                                                                                          40
  Directory structure of an OpenFOAM® case
              Directory structure of a general case
case_name                     case_name: the name of the case directory is given by
├── 0                         the user (do not use white spaces or strange
│   ├── p                     symbols).
                                                                                           41
                       Roadmap
                                                           42
Running my first OpenFOAM® case setup blindfold
Before we start – Always remember the directory structure
                                     case_name
                                     ├── 0
                                     ├── constant
                                     │   └── polyMesh
                                     ├── system
                                     └── time_directories
•   To keep everything in order, the case directory is often located in the path
    $WM_PROJECT_USER_DIR/run.
•   This is not compulsory but highly advisable, you can put the case in any directory of your preference.
•   The name of the case directory if given by the user (do not use white spaces).
•   You run the applications and utilities in the top level of this directory.
•   The directory system contains run-time control and solver numerics.
•   The directory constant contains physical properties, turbulence modeling properties, advanced physics
    and so on.
•   The directory constant/polyMesh contains the polyhedral mesh information.
•   The directory 0 contains boundary conditions (BC) and initial conditions (IC).
                                                                                                             43
    Running my first OpenFOAM® case setup blindfold
             Before we start – Setting OpenFOAM® cases
• As you will see, it is quite difficult to remember all the dictionary files needed to run
  each application.
• It is even more difficult to recall the compulsory and optional entries of each input file.
• When setting a case from scratch in OpenFOAM®, what you need to do is find a
  tutorial or a case that close enough does what you want to do and then you can adapt
  it to your physics.
• Having this in mind, you have two sources of information:
          • $WM_PROJECT_DIR/tutorials
             (The tutorials distributed with OpenFOAM®)
          • $PTOFC
             (The tutorials used during this training)
•    If you use a GUI, things are much easier. However, OpenFOAM® does not come
     with a native GUI interface.
•    We are going to do things in the hard way (and maybe the smart way), we are going
     to use the Linux terminal
                                                                                              44
Running my first OpenFOAM® case setup blindfold
         Flow in a lid-driven square cavity – Re = 100
                      Incompressible flow
                                                                                        45
Running my first OpenFOAM® case setup blindfold
                Workflow of the case
blockMesh
icoFoam functionObjects
sampling paraview
                                                           46
    Running my first OpenFOAM® case setup blindfold
                   A word of caution about the solver icoFoam
                                                                                   47
Running my first OpenFOAM® case setup blindfold
     At the end of the day, you should get something like this
High-Re Solutions for incompressible flow using the navier-stokes equations and a multigrid method
U. Ghia, K. N. Ghia, C. T. Shin.
Journal of computational physics, 48, 387-411 (1982)                                                       49
    Running my first OpenFOAM® case setup blindfold
$PTOFC/101OF/cavity2D
•    In the case directory, you will find the README.FIRST file. In this file, you will find the general instructions of
     how to run the case. In this file, you might also find some additional comments.
•    You will also find a few additional files (or scripts) with the extension .sh, namely, run_all.sh,
     run_mesh.sh, run_sampling.sh, run_solver.sh, and so on. These files can be used to run the case
     automatically by typing in the terminal, for example, sh run_solver.
•    We highly recommend you to open the README.FIRST file and type the commands in the terminal, in this
     way, you will get used with the command line interface and OpenFOAM® commands.
•    If you are already comfortable with OpenFOAM®, use the automatic scripts to run the cases.
                                                                                                                           50
 Running my first OpenFOAM® case setup blindfold
                        Loading OpenFOAM® environment
• If you are using the lab workstations, you will need to source OpenFOAM® (load
  OpenFOAM® environment).
• To use PyFoam (a plotting utility) you will need to source it. Type in the terminal:
         •   $> anaconda3
• Remember, every time you open a new terminal window you need to source
  OpenFOAM® and PyFoam.
• Also, you might need to load OpenFOAM® again after loading PyFoam.
• By default, when installing OpenFOAM® and PyFoam you do not need to do this.
  This is our choice as we have many things installed and we want to avoid conflicts
  between applications.
                                                                                         51
    Running my first OpenFOAM® case setup blindfold
                                  What are we going to do?
•   We will use the lid-driven square cavity tutorial as a general example to show you how to set up
    and run solvers and utilities in OpenFOAM®.
•   In this tutorial we are going to generate the mesh using blockMesh.
•   After generating the mesh, we will look for topological errors and assess the mesh quality. For
    this we use the utility checkMesh. Later on, we are going to talk about what is a good mesh.
•   Then, we will find the numerical solution using icoFoam, which is a transient solver for
    incompressible, laminar flow of Newtonian fluids. By the way, we hope you did not forget where
    to look for this information.
•   And we will finish with some quantitative post-processing and qualitative visualization using
    paraFoam and OpenFOAM® utilities.
•   While we run this case, we are going to see a lot of information on the screen (standard output
    stream or stdout), but it will not be saved. This information is mainly related to convergence of
    the simulation, we will talk about this later on.
•   A final word, we are going to use the solver icoFoam but have in mind that this is a very basic
    solver with no modeling capabilities and limited post-processing features.
•   Therefore, is better to use pisoFoam or pimpleFoam which are equivalent to icoFoam but
    with many more features.
                                                                                                        52
 Running my first OpenFOAM® case setup blindfold
                             Running the case blindfold
• Let us run this case blindfold.
• Later we will study in detail each file and directory.
• Remember, the variable $PTOFC is pointing to the path where you unpacked the
  tutorials.
• You can create this environment variable or write down the path to the directory.
• In the terminal window type:
1. $> cd $PTOFC/101OF/cavity
   2.    $> ls –l
   3.    $> blockMesh
   4.    $> checkMesh
   5.    $> icoFoam
   6.    $> postProcess -func sampleDict -latestTime
   7.    $> gnuplot gnuplot/gnuplot_script
   8.    $> paraFoam
                                                                                      53
    Running my first OpenFOAM® case setup blindfold
                                   Running the case blindfold
•   In step 1 we go to the case directory. Remember, $PTOFC is pointing to the path where you
    unpacked the tutorials.
•   In step 2 we just list the directory structure (this step is optional). Does it look familiar to you? In
    the directory 0 you will the initial and boundary conditions, in the constant directory you will
    find the mesh information and physical properties, and in the directory system you will find the
    dictionaries that controls the numerics, runtime parameters and sampling.
•   In step 3 we generate the mesh.
•   In step 4 we check the mesh quality. We are going to address how to assess mesh quality later
    on.
•   In step 5 we run the simulation. This will show a lot information on the screen, the standard
    output stream will not be saved.
•   In step 6 we use the utility postProcess to do some sampling only of the last saved solution
    (the latestTime flag). This utility will read the dictionary file named sampleDict located in
    the directory system.
•   In step 7 we use a gnuplot script to plot the sampled values. Feel free to take a look and reuse
    this script.
•   Finally, in step 8 we visualize the solution using paraFoam. In the next slides we are going to
    briefly explore this application.
                                                                                                           54
Running my first OpenFOAM® case setup blindfold
                        Crash introduction to paraFoam
       Menu Bar
       Toolbars
Pipeline Browser
Properties panel
 Apply button
 Press this button to
 load the case or to
 apply a filter
                                                         3D View/Canvas
                                 Advanced Toggle
                                                                          55
Running my first OpenFOAM® case setup blindfold
         Crash introduction to paraFoam – Toolbars
                             •   Main Controls
• Representation Toolbar
• Common Filters
                                                                                                                              57
Running my first OpenFOAM® case setup blindfold
   Crash introduction to paraFoam – 3D View and mouse interaction
                           Select view orientation in the Camera Controls
Rotate
Zoom
Pan
Zoom
3D View/Canvas
                                                                                             58
 Running my first OpenFOAM® case setup blindfold
                      Crash introduction to paraFoam – Fields visualization
                                     Select Last Frame in the VCR Controls          Current Time Controls
                                                                                                            59
    Running my first OpenFOAM® case setup blindfold
                           Crash introduction to paraFoam – Filters
•    Filters are functions that generate, extract or derive features from the input data.
•    They are attached to the input data.
•    You can access the most commonly used filters from the Common Filters toolbar
• You can access all the filters from the menu Filter.
                                                                                            60
  Running my first OpenFOAM® case setup blindfold
                                  Crash introduction to paraFoam – Filters
                                                                             61
Running my first OpenFOAM® case setup blindfold
                                 Crash introduction to paraFoam – Slice filter
4. Press Apply
                                                                                 62
Running my first OpenFOAM® case setup blindfold
                             Crash introduction to paraFoam – Glyph filter
                                                          4. Color the colors using Solid Color
1. Select the Glyph filter. This
filter will be applied on the
Slice1 filter
3. Press Apply
2. Filter options
                                                                                                  63
  Running my first OpenFOAM® case setup blindfold
                      Crash introduction to paraFoam – Plot Over Line filter
  1.a. Select the Plot Over Line
  filter.
(0.5, 1, 1)
3. Press Apply
                                                                  (0.5, 0, 1)
    2. Enter the coordinates of the line
Line
                                                                                64
Running my first OpenFOAM® case setup blindfold
                                  Crash introduction to paraFoam – Filters
            4. Optional – Use the VCR Control to change the frame.
            The line chart view will be updated automatically
1. Click on the line chart view (the blue frame indicates that it is the active view)
                                                                                                                               65
 Running my first OpenFOAM® case setup blindfold
                     Running the case blindfold with log files
• In the previous case, we ran the simulation but we did not save the standard output
  stream (stdout) in a log file.
• Our advice is to always save the standard output stream (stdout) in a log file.
• It is of interest to always save the log as if something goes wrong and you would like
  to do troubleshooting, you will need this information.
• Also, if you are interested in plotting the residuals you will need the log file.
• By the way, if at any point you ask us what went wrong with your simulation, it is likely
  that we will ask you for this file.
                                                                                          66
 Running my first OpenFOAM® case setup blindfold
                         Running the case blindfold with log files
• There are many ways to save the log files.
• From now on, we will use the Linux tee command to save log files.
• To save a log file of the simulation or the output of any utility, you can proceed as
  follows:
   1.     $> foamCleanTutorials
   2.     $> blockMesh | tee log.blockMesh
   3.     $> checkMesh | tee log.checkMesh
   4.     $> icoFoam | tee log.icoFoam
• You can use your favorite text editor to read the log file (e.g., gedit, vi, emacs).
                                                                                          67
    Running my first OpenFOAM® case setup blindfold
                        Running the case blindfold with log files
•   In step 1 we erase the mesh and all the folders, except for 0, constant and system. This
    script comes with your OpenFOAM® installation.
•   In step 2, we generate the mesh using the meshing tool blockMesh. We also redirect the
    standard output to an ascii file with the name log.blockMesh (it can be any name). The tee
    command will redirect the screen output to the file log.blockMesh and at the same time will
    show you the information on the screen.
•   In step 3 we check the mesh quality. We also redirect the standard output to an ascii file with the
    name log.checkMesh (it can be any name).
•   In step 4 we run the simulation. We also redirect the standard output to an ascii file with the
    name log.icoFoam (it can be any name). Remember, the tee command will redirect the
    screen output to the file log.icoFoam and at the same time will show you the information on
    the screen.
•   To postprocess the information contained in the solver log file log.icoFoam, we can use the
    utility foamLog. Type in the terminal:
           •   $> foamLog log.icoFoam
•   This utility will extract the information inside the file log.icoFoam. The extracted information is
    saved in an editable/plottable format in the directory logs.
•   At this point we can use gnuplot to plot the residuals. Type in the terminal:
           •   $> gnuplot                                                                             68
 Running my first OpenFOAM® case setup blindfold
                                 Running the case blindfold with log files
• To plot the information extracted with foamLog using gnuplot, we can proceed as
  follows (remember, at this point we are using the gnuplot prompt):
  1.   gnuplot> set logscale y
       Set log scale in the y axis
  3.   gnuplot> plot ‘logs/p_0’ using 1:2 with lines, ‘logs/pFinalRes_0’ using 1:2 with lines
       Here we are plotting to different files. You can concatenate files using comma (,)
  4.   gnuplot> reset
       To reset the scales
  7.   gnuplot> plot [30:50][] ‘logs/Ux_0’ u 1:2 w l title ‘Ux’,‘logs/Uy_0’ u 1:2 w l title ‘Uy’
       Set the x range from 30 to 50 and plot tow files and set legend titles
  8.   gnuplot> exit
       To exit gnuplot
                                                                                                                             69
 Running my first OpenFOAM® case setup blindfold
                     Running the case blindfold with log files
• The output of step 3 is the following:
• The fact that the initial residuals (red line) are dropping to the same value of the final
  residuals (monotonic convergence), is a clear indication of a steady behavior.
                                                                                               70
    Running my first OpenFOAM® case setup blindfold
      Running the case blindfold with log files and plotting the residuals
•   It is also possible to plot the log information on the fly.
•   The easiest way to do this is by using PyFoam (you will need to install it):
            •    $> pyFoamPlotRunner.py [options] <foamApplication>
•    If you are using the lab workstations, you will need to source PyFoam. To source PyFoam, type in the
     terminal:
            •    $> anaconda3
•   If you need help or want to know all the options available,
            •    $> pyFoamPlotRunner.py –-help
•   To run this case with pyFoamPlotRunner.py, in the terminal type:
            •    $> pyFoamPlotRunner.py icoFoam
•   If you do not feel comfortable using pyFoamPlotRunner.py to run the solver, it is also possible to plot the
    information saved in the log file using PyFoam.
•   To do so you will need to use the utility pyFoamPlotWatcher.py. For example,
            •   $> icoFoam | tee log.icoFoam
•   Then, in a new terminal window launch pyFoamPlotWatcher, as follows,
            •    $> pyFoamPlotWatcher.py log.icoFoam
•   You can also use pyFoamPlotWatcher.py to plot the information saved in an old log file.
                                                                                                                  71
 Running my first OpenFOAM® case setup blindfold
    Running the case blindfold with log files and plotting the residuals
• This is a screenshot on my computer. In this case, pyFoamPlotRunner is plotting
  the initial residuals and continuity errors on the fly.
                                                                                    72
    Running my first OpenFOAM® case setup blindfold
                                         Stopping the simulation
•   Your simulation will automatically stop at the time value you set using the keyword endTime in
    the controlDict dictionary.
                endTime 50;
•   If for any reason you want to stop your simulation before reaching the value set by the keyword
    endTime, you can change this value to a number lower than the current simulation time (you
    can use 0 for instance). This will stop your simulation, but it will not save your last time-step or
    iteration, so be careful.
                      1    /*--------------------------------*- C++ -*----------------------------------*\
                      2    | =========                 |                                                 |
                      3    | \\      / F ield           | OpenFOAM: The Open Source CFD Toolbox          |
                      4    | \\     /   O peration      | Version: 8                                     |
                      5    |   \\ /     A nd           | Web:       www.OpenFOAM.org                     |
                      6    |    \\/     M anipulation |                                                  |
                      7    \*---------------------------------------------------------------------------*/
                      8    FoamFile
                      9    {
                      10       version     2.0;
                      11       format      ascii;
                      12       class       dictionary;
                      13       object      controlDict;
                      14   }
                      15   // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
                      16
                      17   application    icoFoam;
                      18
                      19   startFrom      startTime;
                      20
                      21   startTime      0;
                      22
                      23   stopAt         endTime;
                      24
                      25   endTime        50;
                                                                                                             73
    Running my first OpenFOAM® case setup blindfold
                                          Stopping the simulation
•   If you want to stop the simulation and save the solution, in the controlDict dictionary made
    the following modification,
                stopAt      writeNow;
    This will stop your simulation and will save the current time-step or iteration.
                                                                                                              74
 Running my first OpenFOAM® case setup blindfold
                                   Stopping the simulation
• The previous modifications can be done on-the-fly, but you will need to set the
  keyword runTimeModifiable to true in the controlDict dictionary.
• By setting the keyword runTimeModifiable to true, you will be able to modify most of
  the dictionaries on-the-fly.
                  44
                  45   runTimeModifiable true;
                  46
                                                                                                         75
    Running my first OpenFOAM® case setup blindfold
                                        Stopping the simulation
•   You can also kill the process. For instance, if you did not launch the solver in background, go to its terminal
    window and press ctrl-c. This will stop your simulation, but it will not save your last time-step or iteration, so
    be careful.
•   If you launched the solver in background, just identify the process id using top or htop (or any other process
    manager) and terminate the associated process. Again, this will not save your last time-step or iteration.
•   To identify the process id of the OpenFOAM® solver or utility, just read screen. At the beginning of the output
    screen, you will find the process id number.
                 /*---------------------------------------------------------------------------*\
                 | =========                  |                                                |
                 | \\        / F ield         | OpenFOAM: The Open Source CFD Toolbox          |
                 | \\      /    O peration    | Version: 8                                     |
                 |    \\ /      A nd          | Web:      www.OpenFOAM.org                     |
                 |     \\/      M anipulation |                                                |
                 \*---------------------------------------------------------------------------*/
                 Build : 4.x-e964d879e2b3
                 Exec    : icoFoam
                 Date    : Mar 11 2017
                 Time    : 23:21:50
                 Host    : "linux-ifxc"
                 PID     : 3100                                                                Process   id number
                 Case    : /home/joegi/my_cases_course/5x/101OF/cavity
                 nProcs : 1
                 sigFpe : Enabling floating point exception trapping (FOAM_SIGFPE).
                 fileModificationChecking : Monitoring run-time modified files using timeStampMaster
                 allowSystemOperations : Allowing user-supplied system call operations
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
                                                                                                                    76
    Running my first OpenFOAM® case setup blindfold
                                    Stopping the simulation
•   When working locally, we usually proceed in this way:
    This will run the solver icoFoam (by the way, this works for any solver or utility), it will save the
    standard output stream in the file log.icofoam and will show the solver output on the fly.
•   If at any moment we want to stop the simulation, and we are not interested in saving the last
    time-step, we press ctrl-c.
•   If we are interested in saving the last time step, we modify the controlDict dictionary and
    add the following keyword
                 stopAt    writeNow;
•   Remember, this modification can be done on the fly. However, you will need to set the keyword
    runTimeModifiable to yes in the controlDict dictionary.
                                                                                                            77
    Running my first OpenFOAM® case setup blindfold
                                   Cleaning the case folder
•   If you want to erase the mesh and the solution in the current case folder, you can type in the
    terminal,
                $> foamCleanTutorials
    If you are running in parallel, this will also erase the processorN directories. We will talk about
    running in parallel later.
•   If you are looking to only erase the mesh, you can type in the terminal,
                $> foamCleanPolyMesh
•   If you are only interested in erasing the saved solutions, in the terminal type,
                $> foamListTimes -rm
•   If you are running in parallel and you want to erase the solution saved in the processorN
    directories, type in the terminal,
                $> foamListTimes –rm -processor
                                                                                                      78
                       Roadmap
                                                           79
  A deeper view to my first OpenFOAM® case setup
• We will take a close look at what we did by looking at the case files.
• The case directory originally contains the following sub-directories: 0, constant, and
  system. After running icoFoam it also contains the time step directories 1, 2, 3,
  ..., 48, 49, 50, the post-processing directory postProcessing, and the
  log.icoFoam file (if you chose to redirect the standard output stream).
    • The time step directories contain the values of all the variables at those time
      steps (the solution). The 0 directory is thus the initial condition and boundary
      conditions.
    • The constant directory contains the mesh and dictionaries for thermophysical,
      turbulence models and advanced physical models.
    • The system directory contains settings for the run, discretization schemes and
      solution procedures.
    • The postProcessing directory contains the information related to the
      functionObjects (we are going to address functionObjects later).
• The icoFoam solver reads these files and runs the case according to those
  settings.
                                                                                         80
  A deeper view to my first OpenFOAM® case setup
• Before continuing, we want to point out the following:
    • Each dictionary file in the case directory has a header.
    • Lines 1-7 are commented.
    • You should always keep lines 8 to 14, if not, OpenFOAM® will complain.
    • According to the dictionary you are using, the class keyword (line 12)
      will be different. We are going to talk about this later on.
    • From now on and unless it is strictly necessary, we will not show the
      header when listing the dictionaries files.
                                                                                                       81
A deeper view to my first OpenFOAM® case setup
                                                 82
  A deeper view to my first OpenFOAM® case setup
                                The constant directory
                       (and by the way, open each file and go thru its content)
• In this directory you will find the sub-directory polyMesh and the dictionary file
  transportProperties.
• The transportProperties file is a dictionary for the dimensioned scalar nu, or the
  kinematic viscosity.
1 Mass Kilogram kg
2 Length meters m
3 Time second s
4 Temperature Kelvin K
6 Current ampere A
                                                                           84
  A deeper view to my first OpenFOAM® case setup
                                The constant directory
                       (and by the way, open each file and go thru its content)
17 nu nu [ 0 2 -1 0 0 0 0 ] 0.01;
[ 0 m^2 s^-1 0 0 0 0 ]
Which is equivalent to
                                                                                  85
  A deeper view to my first OpenFOAM® case setup
                               The constant directory
                      (and by the way, open each file and go thru its content)
• In this case, as we are working with an incompressible flow, we only need to define
  the kinematic viscosity.
• Later on, we will ask you to change the Reynolds number, to do so you can change
  the value of nu. Remember,
• You can also change the free stream velocity U or the reference length L.
                                                                                        86
  A deeper view to my first OpenFOAM® case setup
                                The constant directory
                       (and by the way, open each file and go thru its content)
• Depending on the physics involved and models used, you will need to define more
  variables in the dictionary transportProperties.
• For instance, for a multiphase case you will need to define the density rho and
  kinematic viscosity nu for each single phase. You will also need to define the surface
  tension .
• Also, depending of your physical model, you will find more dictionaries in the constant
  directory.
• For example, if you need to set gravity, you will need to create the dictionary g.
• If you work with compressible flows you will need to define the dynamic viscosity mu,
  and many other physical properties in the dictionary thermophysicalProperties.
• As we are not dealing with compressible flows (for the moment), we are not going into
  details.
                                                                                        87
  A deeper view to my first OpenFOAM® case setup
                        The constant/polyMesh directory
                       (and by the way, open each file and go thru its content)
• In this case, the polyMesh directory is initially empty. After generating the mesh, it
  will contain the mesh in OpenFOAM® format.
• To generate the mesh in this case, we use the utility blockMesh. This utility reads
  the dictionary blockMeshDict located in the system folder.
• We will briefly address a few important inputs of the blockMeshDict dictionary.
• Do not worry, we are going to revisit this dictionary during the meshing session.
• However, have in mind that rarely you will use this utility to generate a mesh for
  complex geometries.
• Go to the directory system and open blockMeshDict dictionary with your favorite
  text editor, we will use gedit.
                                                                                           88
  A deeper view to my first OpenFOAM® case setup
                                       The system/blockMeshDict dictionary
• The blockMeshDict dictionary first defines a list with a number of vertices:
                                                        •   The keyword convertToMeters (line 17), is a scaling factor. In this case
 17   convertToMeters 1;
 18
                                                            we do not scale the dimensions.
 19   xmin   0;
 20   xmax   1;                                         •   In the section vertices (lines 37-58), we define the vertices coordinates of
 21   ymin   0;                                             the geometry. In this case, there are eight vertices defining the geometry.
 22   ymax   1;
 23   zmin   0;
                                                            OpenFOAM® always uses 3D meshes, even if the simulation is 2D.
 24   zmax   1;
 25                                                     •   We can directly define the vertex coordinates in the section vertices
 26   xcells 20;                                            (commented lines 49-56), or we can use macro syntax.
 27   ycells 20;
 28   zcells 1;                                         •   Using macro syntax we first define a variable and its value (lines 19-24),
 29
 37   vertices                                              and then we can use them by adding the symbol $ to the variable name
 38   (                                                     (lines 39-46).
 39       ($xmin      $ymin   $zmin)     //vertex   0
 40       ($xmax      $ymin   $zmin)     //vertex   1   •   In lines 26-28, we define a set of variables that will be used at a later time.
 41       ($xmax      $ymax   $zmin)     //vertex   2
 42       ($xmin      $ymax   $zmin)     //vertex   3       These variables are related to the number of cells in each direction.
 43       ($xmin      $ymin   $zmax)     //vertex   4
 44       ($xmax      $ymin   $zmax)     //vertex   5   •   Finally, notice that the vertex numbering starts from 0 (as the counters in
 45       ($xmax      $ymax   $zmax)     //vertex   6       c++). This numbering applies for blocks as well.
 46       ($xmin      $ymax   $zmax)     //vertex   7
 47
 48   /*
 49        (0   0   0)
 50        (1   0   0)
 51        (1   1   0)
 52        (0   1   0)
 53        (0   0   0.1)
 54        (1   0   0.1)
 55        (1   1   0.1)
 56        (0   1   0.1)
 57   */
 58   );
                                                                                                                                           89
  A deeper view to my first OpenFOAM® case setup
                                The system/blockMeshDict dictionary
• The blockMeshDict dictionary also defines the boundary patches:
• To sum up, the blockMeshDict dictionary generates in this case a single block with:
        • X/Y/Z dimensions: 1.0/1.0/1.0
        • Cells in the X, Y and Z directions: 20 x 20 x 1 cells.
        • One single hex block with straight lines.
        • Patch type wall and patch name fixedWalls at three sides.
        • Patch type wall and patch name movingWall at one side.
        • Patch type empty and patch name frontAndBack patch at two sides.
• If you are interested in visualizing the actual block topology, you can use paraFoam
  as follows,
        • $> paraFoam –block
                                                                                         91
  A deeper view to my first OpenFOAM® case setup
                     The system/blockMeshDict dictionary
                                                                                     92
  A deeper view to my first OpenFOAM® case setup
              The constant/polyMesh/boundary dictionary
• First of all, this file is automatically generated after you create the mesh
  using blockMesh or snappyHexMesh, or when you convert the mesh from
  a third-party format.
• In this file, the geometrical information related to the base type patch of
  each boundary (or surface patch) of the domain is specified.
• The base type boundary condition is the actual surface patch where we are
  going to apply a numerical type boundary condition (or numerical boundary
  condition).
• The numerical type boundary condition assign a field value to the surface
  patch (base type).
• We define the numerical type patch (or the value of the boundary
  condition), in the directory 0 or time directories.
                                                                                93
  A deeper view to my first OpenFOAM® case setup
                   The constant/polyMesh/boundary dictionary
                                                                                                      fixedWall
                                           fixedWall
 34       frontAndBack
 35       {
 36           type        empty;
 37           inGroups    1(empty);
 38           nFaces      800;
 39           startFace   840;
 40       }
 41   )
                                                                                                frontAndBack
fixedWall
                                                                                                                  94
  A deeper view to my first OpenFOAM® case setup
                   The constant/polyMesh/boundary dictionary
 18   3
 19   (                                      Name and type of the surface patches
 20       movingWall                  Name
 21       {
 22           type        wall;       Type   •   The name and type of the patch is given by
 23           inGroups    1(wall);
 24           nFaces      20;                    the user.
 25           startFace   760;
 26       }                                  •   In this case the name and type was assigned
 27       fixedWalls                             in the dictionary blockMeshDict.
 28       {
 29           type        wall;              •   You can change the name if you do not like it.
 30           inGroups    1(wall);
 31           nFaces      60;                    Do not use strange symbols or white spaces.
 32           startFace   780;
 33       }                                  •   You can also change the base type. For
 34       frontAndBack                           instance, you can change the type of the
 35       {
 36           type        empty;
                                                 patch movingWall from wall to patch.
 37           inGroups    1(empty);
 38           nFaces      800;
                                             •   When converting the mesh from a third party
 39           startFace   840;                   format, OpenFOAM® will try to recover the
 40       }                                      information from the original format. But it
 41   )
                                                 might happen that it does not recognizes the
                                                 base type and name of the original file. In this
                                                 case you will need to modify this file manually.
                                                                                                  95
  A deeper view to my first OpenFOAM® case setup
                   The constant/polyMesh/boundary dictionary
 18   3                               inGroups keyword
 19   (                               •   This keyword is optional. You can erase this information safely.
 20       movingWall
 21       {                           •   It is used to group patches during visualization in
 22           type        wall;           ParaView/paraFoam. If you open this mesh in paraFoam you will
 23           inGroups    1(wall);        see that there are two groups, namely: wall and empty.
 24           nFaces      20;
 25           startFace   760;        •   As usual, you can change the name.
 26       }                           •   If you want to put a surface patch in two groups, you can proceed
 27       fixedWalls
                                          as follows:
 28       {
 29           type        wall;                    2(wall wall1)
 30           inGroups    1(wall);
 31           nFaces      60;
                                          In this case the surface patch belongs to the groups wall and
 32           startFace   780;            wall1.
 33       }                           •   Groups can have more than one patch.
 34       frontAndBack
 35       {
 36           type        empty;      nFaces and startFace keywords
 37           inGroups    1(empty);
 38           nFaces      800;        •   Unless you know what you are doing, you do not need to
 39           startFace   840;            modify this information.
 40       }
 41   )                               •   This information is related to the starting face and ending face of
                                          the boundary patch in the mesh data structure.
                                      •   This information is created automatically when generating the
                                          mesh or converting the mesh.
                                                                                                                96
    A deeper view to my first OpenFOAM® case setup
                   The constant/polyMesh/boundary dictionary
•   There are a few base type patches that are constrained or paired. This means that the type
    should be the same in the boundary file and in the numerical boundary condition defined in the
    field files, e.g., the files 0/U and 0/p.
•   In this case, the base type of the patch frontAndBack (defined in the file boundary), is
    consistent with the numerical type patch defined in the field files 0/U and 0/p. They are of
    the type empty.
•   Also, the base type of the patches movingWall and fixedWalls (defined in the file boundary),
    is consistent with the numerical type patch defined in the field files 0/U and 0/p.
•   This is extremely important, especially if you are converting meshes as not always the type of
    the patches is set as you would like.
•   Hence, it is highly advisable to do a sanity check and verify that the base type of the patches
    (the type defined in the file boundary), is consistent with the numerical type of the patches
    (the patch type defined in the field files contained in the directory 0 (or whatever time directory
    you defined the boundary and initial conditions).
•   If the base type and numerical type boundary conditions are not consistent, OpenFOAM® will
    complain.
•   Do not worry, we are going to address boundary conditions later on.
                                                                                                          97
  A deeper view to my first OpenFOAM® case setup
              The constant/polyMesh/boundary dictionary
                 symmetry                          symmetry
               symmetryPlane                     symmetryPlane
                   empty                             empty
                   wedge                            wedge
                   cyclic                            cyclic
                 processor                         processor
                                                                            98
  A deeper view to my first OpenFOAM® case setup
             The constant/polyMesh/boundary dictionary
• The base type patch can be any of the numerical or derived type
  boundary conditions available in OpenFOAM®. Mathematically speaking;
  they can be Dirichlet, Neumann or Robin boundary conditions.
                                                           fixedValue
                                                         zeroGradient
                                                           inletOutlet
                                                                 slip
                  patch
                                                        totalPressure
                                                supersonicFreeStream
                                                          and so on …
                                      Refer to the doxygen documentation for a list of all numerical
                                                   type boundary conditions available.
                                                                                                       99
  A deeper view to my first OpenFOAM® case setup
              The constant/polyMesh/boundary dictionary
                                      type fixedValue;
                  wall                                           zeroGradient
                                      value uniform (U V W);
• This boundary condition is not contained in the patch base type boundary
  condition group, because specialize modeling options can be used on this
  boundary condition.
• An example is turbulence modeling, where turbulence can be generated or
  dissipated at the walls.
                                                                                100
  A deeper view to my first OpenFOAM® case setup
              The constant/polyMesh/boundary dictionary
• The name of the base type boundary condition and the name of the
  numerical type boundary condition needs to be the same, if not,
  OpenFOAM® will complain.
• Pay attention to this, specially if you are converting the mesh from another
  format.
• As you can see, all the names are the same across all the dictionary files.
                                                                                 101
    A deeper view to my first OpenFOAM® case setup
                                      The system directory
                           (and by the way, open each file and go thru its content)
                                                                                                                     103
     A deeper view to my first OpenFOAM® case setup
                                    The controlDict dictionary
                                       • So how do we know what options are available for each keyword?
                                       • The hard way is to refer to the source code.
                                       • The easy way is to use the banana method.
17    application      icoFoam;
18                                     • So what is the banana method? This method consist in inserting a dummy word
19    startFrom        startTime;
20
                                         (that does not exist in the installation) and let OpenFOAM® list the available
21    startTime        0;                options.
22
23    stopAt           banana;         • For example. If you add banana in line 23, you will get this output:
24
25    endTime          50;
                                                banana is not in enumeration
26                                              4
27    deltaT           0.01;
28                                              (
29    writeControl     runTime;
30                                              nextWrite
31    writeInterval    1;
32                                              writeNow
33    purgeWrite       0;
34
                                                noWriteNow
35    writeFormat      ascii;                   endTime
36
37    writePrecision   8;                       )
38
39    writeCompression off;            • So your options are nextWrite, writeNow, noWriteNow, endTime
40
41    timeFormat       general;        • And how do we know that banana does not exist in the source code? Just type in
42                                       the terminal:
43    timePrecision    6;
44                                            • $> src
45    runTimeModifiable true;
                                             • $> grep –r –n banana .
                                       • If you see some bananas in your output someone is messing around with your
                                         installation.
                                       • Remember, you can use any dummy word, but you have to be sure that it does
                                         not exist in OpenFOAM®.
                                                                                                                      104
     A deeper view to my first OpenFOAM® case setup
                                    The controlDict dictionary
                                                                                                             105
 A deeper view to my first OpenFOAM® case setup
                                            The fvSchemes dictionary
17   solvers
                                                     • To solve U we are using the smoothSolver method, with the
18   {                                                 smoother symGaussSeidel, an absolute tolerance equal to
19       p
20       {                                             1e-08 and a relative tolerance relTol equal to 0.
21             solver           PCG;
22             preconditioner   DIC;                 • The solvers will iterative until reaching any of the tolerance
23             tolerance        1e-06;
24             relTol           0;                     values set by the user or reaching a maximum value of
39       }
                                                       iterations (optional entry).
40
41       pFinal                                      • FYI, solving for the velocity is relative inexpensive, whereas
42
43
         {
             $p;
                                                       solving for the pressure is expensive.
44           relTol             0;
45       }                                           • The PISO sub-dictionary contains entries related to the
46
47       U
                                                       pressure-velocity coupling method (the PISO method).
48       {
49             solver           smoothSolver;        • In this case we are doing only one PISO correction and no
50             smoother         symGaussSeidel;
51             tolerance        1e-08;
                                                       orthogonal corrections.
52             relTol           0;
53       }                                           • You need to do at least one PISO loop (nCorrectors).
54   }
55
56   PISO
57   {
58       nCorrectors     1;
59       nNonOrthogonalCorrectors 0;
60       pRefCell        0;
61       pRefValue       0;
62   }
                                                                                                                        108
  A deeper view to my first OpenFOAM® case setup
                              The system directory
                                (optional dictionary files)
• In the system directory you will also find these two additional files:
        • decomposeParDict
        • sampleDict
                                                                                    109
 A deeper view to my first OpenFOAM® case setup
                                           The sampleDict dictionary
                                                      Type of sampling, sets will sample along a line.
                                                       Format of the output file, raw format is a generic format
17   type sets;                                        that can be read by many applications. The output file is
18
19   setFormat raw;
                                                       human readable (ascii format).
20
23   interpolationScheme cellPointFace;               Interpolation method at the solution level (location of the
24
26   fields                                           interpolation points).
27   (
28       U                                            Fields to sample.
29   );
30
31   sets
32   (
33                                                    Sample method. How to interpolate the solution to the
34
35
          l1
          {
                                                      sample entity (line in this case)
38             type         lineFace;
43             axis         x;
44             start        ( -1 0.5 0);              Location of the sample line. We define start and end
45
46        }
               end          ( 2 0.5 0);               point, and the axis of the sampling.
47
48        l2
49        {
52
57
               type
               axis
                            lineFace;
                            y;
                                                      Sample method from the solution to the line.
58             start        (0.5 -1 0);
59             end          (0.5 2 0);
60        }
61
62   );
                                                      Location of the sample line. We define start and end
                                                      point, and the axis of the sampling.
                                                                                                                110
 A deeper view to my first OpenFOAM® case setup
                                           The sampleDict dictionary
• The 0 directory contains the initial and boundary conditions for all primitive variables,
  in this case p and U. The U file contains the following information (velocity vector):
                                                                                                                                   112
  A deeper view to my first OpenFOAM® case setup
                                                The 0 directory
                               (and by the way, open each file and go thru its content)
• The 0 directory contains the initial and boundary conditions for all primitive variables,
  in this case p and U. The U file contains the following information (velocity):
• The 0 directory contains the initial and boundary conditions for all primitive variables,
  in this case p and U. The p file contains the following information (modified pressure):
                                                                                                                                   114
  A deeper view to my first OpenFOAM® case setup
                                                  The 0 directory
                               (and by the way, open each file and go thru its content)
• The 0 directory contains the initial and boundary conditions for all primitive variables,
  in this case p and U. The p file contains the following information (modified pressure):
                                                                                                           115
    A deeper view to my first OpenFOAM® case setup
with units
                                                                                                   116
    A deeper view to my first OpenFOAM® case setup
•   Coming back to the headers, and specifically the headers related to the field variable
    dictionaries (e.g. U, p, gradU, and so on).
•   In the header of the field variables, the class type should be consistent with the type
    of field variable you are using.
•   Be careful with this, specially if you are copying and pasting files.
•   If the field variable is a scalar, the class should be volScalarField.
                                                                                           117
    A deeper view to my first OpenFOAM® case setup
•   If the field variable is a vector, the class should be volVectorField.
         /*--------------------------------*- C++ -*----------------------------------*\
         | =========                   |                                               |
         | \\         / F ield         | OpenFOAM: The Open Source CFD Toolbox         |
         | \\       /   O peration     | Version: 8                                    |
         |    \\ /      A nd           | Web:      www.OpenFOAM.org                    |
         |     \\/      M anipulation |                                                |
         \*---------------------------------------------------------------------------*/
         FoamFile
         {
              version      2.0;
              format       ascii;
              class        volVectorField;
              object       U;
         }
•   If the field variable is a tensor (e.g. the velocity gradient tensor), the class should be
    volTensorField.
         /*--------------------------------*- C++ -*----------------------------------*\
         | =========                   |                                               |
         | \\         / F ield         | OpenFOAM: The Open Source CFD Toolbox         |
         | \\       /   O peration     | Version: 8                                    |
         |    \\ /      A nd           | Web:      www.OpenFOAM.org                    |
         |     \\/      M anipulation |                                                |
         \*---------------------------------------------------------------------------*/
         FoamFile
         {
              version      2.0;
              format       ascii;
              class        volTensorField;
              object       gradU;
         }                                                                                   118
  A deeper view to my first OpenFOAM® case setup
                                            The output screen
• Finally, let us talk about the output screen, which shows a lot of information.
                                                                                                    Velocity residuals
                          Simulation time
                                                     Courant number
                                                                                                Pressure residuals
                                                                                                No orthogonal corrections
                                                                                                Only one PISO correction
                                               Execution time (wall time)
Continuity errors
                                                                            Additional information
                   End of the simulation                                    Minimum and maximum values of each field
                                                                                                                         119
    A deeper view to my first OpenFOAM® case setup
                                                      The output screen
•   By default, OpenFOAM® does not show the minimum and maximum information. To print out this information,
    we use functionObjects. We are going to address functionObjects in detail when we deal with post-
    processing and sampling.
•   But for the moment, what we need to know is that we add functionObjects at the end of the controlDict
    dictionary. In this case, we are using a functionObject that prints the minimum and maximum information of
    the selected fields.
•   This information complements the residuals information and it is saved in the postProcessing directory. It
    gives a better indication of stability, boundedness and consistency of the solution.
     49   functions
     50   {
     51                                                                                 Name of the folder where the output of
     52   ///////////////////////////////////////////////////////////////////////////   the functionObject will be saved
     53
     54   minmaxdomain
     55   {
     56       type fieldMinMax;                                                         functionObject to use
     57
     58        functionObjectLibs ("libfieldFunctionObjects.so");
     59
     60        enabled true; //true or false                                            Turn on/off functionObject
     61
     62        mode component;
     63
     64        writeControl timeStep;
     65        writeInterval 1;                                                         Output interval of functionObject
     66
     67        log true;                                                                Save output of the functionObject in a ascii file
     68
     69        fields (p U);                                                            Field variables to sample
     70   }
     91
     92   };
                                                                                                                                        120
    A deeper view to my first OpenFOAM® case setup
                                     The output screen
•   Another very important output information is the CFL or Courant number.
•   The Courant number imposes the CFL number condition, which is the maximum allowable
    CFL number a numerical scheme can use. For the n - dimensional case, the CFL number
    condition becomes,
•   In OpenFOAM®, most of the solvers are implicit, which means they are unconditionally
    stable. In other words, they are not constrained to the CFL number condition.
•   However, the fact that you are using a numerical method that is unconditionally stable, does
    not mean that you can choose a time step of any size.
•   The time-step must be chosen in such a way that it resolves the time-dependent features, and it
    maintains the solver stability.
•   For the moment and for the sake of simplicity, let us try to keep the CFL number below 5.0 and
    preferably close to 1.0 (for good accuracy).
•   Other properties of the numerical method that you should observe are: conservationess,
    boundedness, transportiveness, and accuracy. We are going to address these properties and
    the CFL number when we deal with the FVM theory.                                          121
    A deeper view to my first OpenFOAM® case setup
                                                        The output screen
•    To control the CFL number you can change the time step or you can change the mesh.
•    The easiest way is by changing the time step.
•    For a time step of 0.01 seconds, this is the output you should get for this case,
    Time = 49.99
                                                                                                                      CFL number at
    Courant Number mean: 0.044365026 max: 0.16800273
                                                                                                                      time step n - 1
    smoothSolver: Solving for Ux, Initial residual = 1.1174405e-09, Final residual = 1.1174405e-09, No Iterations 0
    smoothSolver: Solving for Uy, Initial residual = 1.4904251e-09, Final residual = 1.4904251e-09, No Iterations 0
    DICPCG: Solving for p, Initial residual = 6.7291723e-07, Final residual = 6.7291723e-07, No Iterations 0
    time step continuity errors : sum local = 2.5096865e-10, global = -1.7872395e-19, cumulative = 2.6884327e-18
    ExecutionTime = 4.47 s ClockTime = 5 s
    Time = 50
                                                                                                                      CFL number at
    Courant Number mean: 0.044365026 max: 0.16800273
    smoothSolver: Solving for Ux, Initial residual = 1.0907508e-09, Final residual = 1.0907508e-09, No Iterations 0   time step n
    smoothSolver: Solving for Uy, Initial residual = 1.4677462e-09, Final residual = 1.4677462e-09, No Iterations 0
    DICPCG: Solving for p, Initial residual = 1.0020944e-06, Final residual = 1.0746895e-07, No Iterations 1
    time step continuity errors : sum local = 4.0107145e-11, global = -5.0601748e-20, cumulative = 2.637831e-18
    ExecutionTime = 4.47 s ClockTime = 5 s
                                                                                                                                        122
    A deeper view to my first OpenFOAM® case setup
                                                        The output screen
•    To control the CFL number you can change the time step or you can change the mesh.
•    The easiest way is by changing the time step.
•    For a time step of 0.1 seconds, this is the output you should get for this case,
    Time = 49.9
                                                                                                                      CFL number at
    Courant Number mean: 0.4441161 max: 1.6798756
                                                                                                                      time step n - 1
    smoothSolver: Solving for Ux, Initial residual = 0.00016535808, Final residual = 2.7960145e-09, No Iterations 5
    smoothSolver: Solving for Uy, Initial residual = 0.00015920267, Final residual = 2.7704949e-09, No Iterations 5
    DICPCG: Solving for p, Initial residual = 0.0015842846, Final residual = 5.2788554e-07, No Iterations 26
    time step continuity errors : sum local = 8.6128916e-09, global = 3.5439859e-19, cumulative = 2.4940081e-17
    ExecutionTime = 0.81 s ClockTime = 1 s
    Time = 50
                                                                                                                      CFL number at
    Courant Number mean: 0.44411473 max: 1.6798833
    smoothSolver: Solving for Ux, Initial residual = 0.00016378098, Final residual = 2.7690608e-09, No Iterations 5   time step n
    smoothSolver: Solving for Uy, Initial residual = 0.00015720331, Final residual = 2.7354499e-09, No Iterations 5
    DICPCG: Solving for p, Initial residual = 0.0015662416, Final residual = 5.2290439e-07, No Iterations 26
    time step continuity errors : sum local = 8.5379223e-09, global = -3.6676527e-19, cumulative = 2.4573316e-17
    ExecutionTime = 0.81 s ClockTime = 1 s
                                                                                                                                        123
    A deeper view to my first OpenFOAM® case setup
                                                        The output screen
•    To control the CFL number you can change the time step or you can change the mesh.
•    The easiest way is by changing the time step.
•    For a time step of 0.5 seconds, this is the output you should get for this case,
    Time = 2
                                                                                                                            CFL number at
    Courant Number mean: 1.6828931 max: 5.6061178
                                                                                                                            time step n - 1
    smoothSolver: Solving for Ux, Initial residual = 0.96587058, Final residual = 4.9900041e-09, No Iterations 27
    smoothSolver: Solving for Uy, Initial residual = 0.88080685, Final residual = 9.7837781e-09, No Iterations 25
    DICPCG: Solving for p, Initial residual = 0.95568243, Final residual = 7.9266324e-07, No Iterations 33
    time step continuity errors : sum local = 6.3955627e-06, global = 1.3227253e-17, cumulative = 1.4125109e-17
    ExecutionTime = 0.04 s ClockTime = 0 s
                                                                                                                                                124
    A deeper view to my first OpenFOAM® case setup
                                                        The output screen
•    Another output you should monitor are the continuity errors.
•    These numbers should be small (it does not matter if they are negative or positive).
•    If these values increase in time (about the order of 1e-2), you better control the case setup because
     something is wrong.
•    The continuity errors are defined in the following file
    $WM_PROJECT_DIR/src/finiteVolume/cfdTools/incompressible/continuityErrs.H
Time = 50
                                                                                                                                      125
    A deeper view to my first OpenFOAM® case setup
                                                    Error output
•   If you forget a keyword or a dictionary file, give a wrong option to a compulsory or optional entry,
    misspelled something, add something out of place in a dictionary, use the wrong dimensions,
    forget a semi-colon and so on, OpenFOAM® will give you the error FOAM FATAL IO ERROR.
•   This error does not mean that the actual OpenFOAM® installation is corrupted. It is telling you
    that you are missing something or something is wrong in a dictionary.
•   Maybe the guys of OpenFOAM® went a little bit extreme here.
                     /*---------------------------------------------------------------------------*\
                     | =========                 |                                                 |
                     | \\      / F ield          | OpenFOAM: The Open Source CFD Toolbox           |
                     | \\     /   O peration     | Version: 8                                      |
                     |   \\ /     A nd           | Web:      www.OpenFOAM.org                      |
                     |    \\/     M anipulation |                                                  |
                     \*---------------------------------------------------------------------------*/
                     Build : 5.x-5d8318b22cbe
                     Exec   : icoFoam
                     Date   : Nov 02 2014
                     Time   : 00:33:41
                     Host   : "linux-cfd"
                     PID    : 3675
                     Case   : /home/cfd/my_cases_course/cavity
                     nProcs : 1
                     sigFpe : Enabling floating point exception trapping (FOAM_SIGFPE).
                     fileModificationChecking : Monitoring run-time modified files using timeStampMaster
                     allowSystemOperations : Allowing user-supplied system call operations
                     // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
                     Create time
                                                                                                           126
    A deeper view to my first OpenFOAM® case setup
                                                   Error output
•   Also, before entering into panic read carefully the output screen because OpenFOAM® is telling
    you what is the error and how to correct it.
                    Build : 6.x-5d8318b22cbe
                    Exec   : icoFoam
                    Date   : Nov 02 2014
                    Time   : 00:33:41
                    Host   : "linux-cfd"
                    PID    : 3675
                    Case   : /home/cfd/my_cases_course/cavity
                    nProcs : 1
                    sigFpe : Enabling floating point exception trapping (FOAM_SIGFPE).
                    fileModificationChecking : Monitoring run-time modified files using timeStampMaster
                    allowSystemOperations : Allowing user-supplied system call operations
                    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
                    Create time
FOAM exiting
                                                                                                                                   127
    A deeper view to my first OpenFOAM® case setup
                                               Error output
•   It is very important to read the screen and understand the output.
• Train yourself to identify the errors. Hereafter we list a few possible errors.
• Missing compulsory file p
FOAM exiting
                                                                                    128
  A deeper view to my first OpenFOAM® case setup
                                              Error output
• Mismatching patch name in file p
FOAM exiting
FOAM exiting
                                                                                                               129
  A deeper view to my first OpenFOAM® case setup
                                              Error output
• Missing entry in file fvSolution at keyword PISO
    --> FOAM FATAL IO ERROR:
    "ill defined primitiveEntry starting at keyword 'PISO' on line 68 and ending at line 68"
FOAM exiting
FOAM aborting
    #0 Foam::error::printStack(Foam::Ostream&) at ??:?
    #1 Foam::error::abort() at ??:?
    #2 void Foam::checkMethod<Foam::Vector<double> >(Foam::fvMatrix<Foam::Vector<double> > const&,
    Foam::fvMatrix<Foam::Vector<double> > const&, char const*) at ??:?
    #3 ? at ??:?
    #4 ? at ??:?
    #5 __libc_start_main in "/lib64/libc.so.6"
    #6 ? at /home/abuild/rpmbuild/BUILD/glibc-2.19/csu/../sysdeps/x86_64/start.S:125
    Aborted                                                                                           130
  A deeper view to my first OpenFOAM® case setup
                                              Error output
• Missing keyword deltaT in file controlDict
FOAM exiting
• Missing file points in directory polyMesh. Likely you are missing the mesh.
        From function Time::findInstance(const fileName&, const word&, const IOobject::readOption, const word&)
        in file db/Time/findInstance.C at line 203.
FOAM exiting
                                                                                                                  131
  A deeper view to my first OpenFOAM® case setup
                                              Error output
• Unknown boundary condition type.
    74
    (
    SRFFreestreamVelocity
    SRFVelocity
    SRFWallVelocity
    activeBaffleVelocity
    ...
    ...
    ...
    variableHeightFlowRateInletVelocity
    waveTransmissive
    wedge
    zeroGradient
    )
FOAM exiting
                                                                                                              132
  A deeper view to my first OpenFOAM® case setup
                                              Error output
• This one is especially hard to spot
    /*---------------------------------------------------------------------------*\
    | =========                  |                                                |
    | \\        / F ield         | OpenFOAM: The Open Source CFD Toolbox          |
    | \\      /    O peration    | Version: 8                                     |
    |    \\ /      A nd          | Web:      www.OpenFOAM.org                     |
    |     \\/      M anipulation |                                                |
    \*---------------------------------------------------------------------------*/
    Build : 6.x-5d8318b22cbe
    Exec    : icoFoam
    Date    : Nov 02 2014
    Time    : 00:33:41
    Host    : "linux-cfd"
    PID     : 3675
    fileName::stripInvalid() called for invalid fileName /home/cfd/my_cases_course/cavity0
         For debug level (= 2) > 1 this is considerd fatal
    Aborted
• This error is related to the name of the working directory. In this case the name of the
  working directory is cavity 0 (there is a blank space between the word cavity and
  the number 0).
• Do not use blank spaces or funny symbols when naming directories and files.
• Instead of cavity 0 you could use cavity_0.
                                                                                             133
    A deeper view to my first OpenFOAM® case setup
                                                Error output
•   You should worry about the SIGFPE error signal. This error signal indicates that something
    went really wrong (erroneous arithmetic operation).
•   This message (that seems a little bit difficult to understand), is giving you a lot information.
•   For instance, this output is telling us that the error is due to SIGFPE and the class associated to
    the error is lduMatrix. It is also telling you that the GAMGSolver solver is the affected one
    (likely the offender is the pressure).
#0 Foam::error::printStack(Foam::Ostream&) at ??:?
#1 Foam::sigFpe::sigHandler(int) at ??:?
#2   in "/lib64/libc.so.6"
#3 Foam::DICPreconditioner::calcReciprocalD(Foam::Field<double>&, Foam::lduMatrix const&) at ??:?
#4 Foam::DICSmoother::DICSmoother(Foam::word const&, Foam::lduMatrix const&, Foam::FieldField<Foam::Field, double>
const&, Foam::FieldField<Foam::Field, double> const&, Foam::UPtrList<Foam::lduInterfaceField const> const&) at ??:?
#5 Foam::lduMatrix::smoother::addsymMatrixConstructorToTable<Foam::DICSmoother>::New(Foam::word const&,
Foam::lduMatrix const&, Foam::FieldField<Foam::Field, double> const&, Foam::FieldField<Foam::Field, double> const&,
Foam::UPtrList<Foam::lduInterfaceField const> const&) at ??:?
#6 Foam::lduMatrix::smoother::New(Foam::word const&, Foam::lduMatrix const&, Foam::FieldField<Foam::Field, double>
const&, Foam::FieldField<Foam::Field, double> const&, Foam::UPtrList<Foam::lduInterfaceField const> const&,
Foam::dictionary const&) at ??:?
#7 Foam::GAMGSolver::initVcycle(Foam::PtrList<Foam::Field<double> >&, Foam::PtrList<Foam::Field<double> >&,
Foam::PtrList<Foam::lduMatrix::smoother>&, Foam::Field<double>&, Foam::Field<double>&) const at ??:?
#8 Foam::GAMGSolver::solve(Foam::Field<double>&, Foam::Field<double> const&, unsigned char) const at ??:?
#9 Foam::fvMatrix<double>::solveSegregated(Foam::dictionary const&) at ??:?
#10 Foam::fvMatrix<double>::solve(Foam::dictionary const&) at ??:?
#11
 at ??:?
#12 __libc_start_main in "/lib64/libc.so.6"
#13
 at /home/abuild/rpmbuild/BUILD/glibc-2.17/csu/../sysdeps/x86_64/start.S:126
Floating point exception                                                                                          134
    A deeper view to my first OpenFOAM® case setup
                                        Dictionary files general features
                                                               /*
           // This is a line comment                                This is a block comment
                                                               */
•   As in C++, you can use the #include directive in your dictionaries (do not forget to create the respective include file):
                            #include “ n t      C nd t n ”
                                                                                                                                135
    A deeper view to my first OpenFOAM® case setup
                                       Dictionary files general features
                     U                                           Sub-dictionary U
                     {
                             solver           PBiCGStab;
                             preconditioner   DILU;
                             tolerance        1e-06;
                             relTol           0;
                     }
                         …
                         …
                         …
                }                                                                                               137
    A deeper view to my first OpenFOAM® case setup
                                      Dictionary files general features
•   Macro expansion.
      •   We first declare a variable (x = 10) and then we use it through the $ macro substitution ($x).
                type             fixedValue;
                value            uniform     $scalarField;                        //Use declared variable
• You can use macro expansion to duplicate and access variables in dictionaries
                            “( eft|r ght|t )W ”
                            {
                                    type fixedValue;
                                    value uniform (0 0 0);
                            }
                            “.*W    ”
                            {
                                    type fixedValue;
                                    value uniform (0 0 0);
                            }
•   Inline calculations.
      •    You can use the directive #calc to do inline calculations, the syntax is as follows:
             X = 10.0;                                                //Declare variable
             Y = 3.0;                                                 //Declare variable
•   With inline calculations you can access all the mathematical functions available in C++.
•   Macro expansions and inline calculations are very useful to parametrize dictionaries and avoid repetitive tasks.
•   Switches: they are used to enable or disable a function or a feature in the dictionaries.
•   Switches are logical values. You can use the following values:
                                                                 Switches
                                                false                                true
                                                  off                                 on
                                                  no                                 yes
                                                  n                                    y
                                                   f                                   t
                                                none                                 true
•   You can find all the valid switches in the following file:
      OpenFOAM-6/src/OpenFOAM/primitives/bools/Switch/Switch.C                                                                     140
  A deeper view to my first OpenFOAM® case setup
                          Solvers and utilities help
• If you need help about a solver or utility, you can use the option –help. For
  instance:
will print some basic help and usage information about icoFoam
• Remember, you have the source code there so you can always
  check the original source.
                                                                              141
    A deeper view to my first OpenFOAM® case setup
                                      Solvers and utilities help
•   To get more information about the boundary conditions, post-processing utilities, and the API read the
    Doxygen documentation.
•   If you did not compile the Doxygen documentation, you can access the information online,
    http://cpp.openfoam.org/v6/
API documentation
                                                                                                             142
    A deeper view to my first OpenFOAM® case setup
                                                   Exercises
•   Run the case with Re = 10 and Re = 1000. Feel free to change any variable to achieve the Re value (velocity,
    viscosity or length). Do you see an unsteady behavior in any of the cases? What about the computing time,
    what simulation is faster?
•   Run the tutorial with Re = 100, a mesh with 120 x 120 x 1 cells, and using the default setup (original
    controlDict, fvSchemes and fvSolution). Did the simulation converge? Did it crash? Any comments.
•   If your simulation crashed, try to solve the problem.
    (Hint: try to reduce the time-step to get a CFL less than 1)
•   Besides reducing the time-step, can you find another solution?
    (Hint: look at the PISO options)
•   Change the base type of the boundary patch movingWall to patch. (the boundary file). Do you get the same
    results? Can you comment on this?
•   Try to extent the problem to 3D and use a uniform mesh (20 x 20 x 20). Compare the solution at the mid
    section of the 3D simulation with the 2D solution. Are the solutions similar?
•   How many time discretization schemes are there in OpenFOAM®? Try to use a different discretization
    scheme.
•   Run the simulation using Gauss upwind instead of Gauss linear for the term div(phi,U) (fvSchemes). Do
    you get the same quantitative results?
•   Sample the field variables U and P at a different location and plot the results using gnuplot.
•   What density value do you think we were using? What about dynamic viscosity?
    Hint: the physical pressure is equal to the modified pressure and                                         143
                       Roadmap
                                                           144
                     3D Dam break – Free surface flow
             blockMesh
                 +
           snappyHexMesh
setFields
interFoam functionObjects
sampling paraview
                                                        146
            3D Dam break – Free surface flow
At the end of the day, you should get something like this
                                                                               147
      3D Dam break – Free surface flow
                                                                        148
                           3D Dam break – Free surface flow
$PTOFC/101OF/3d_damBreak
•   In the case directory, you will find the README.FIRST file. In this file, you will find the general instructions of
    how to run the case. In this file, you might also find some additional comments.
•   You will also find a few additional files (or scripts) with the extension .sh, namely, run_all.sh,
    run_mesh.sh, run_sampling.sh, run_solver.sh, and so on. These files can be used to run the case
    automatically by typing in the terminal, for example, sh run_solver.
•   We highly recommend you to open the README.FIRST file and type the commands in the terminal, in this
    way, you will get used with the command line interface and OpenFOAM® commands.
•   If you are already comfortable with OpenFOAM®, use the automatic scripts to run the cases.
                                                                                                                      149
                     3D Dam break – Free surface flow
                                                                                           150
                   3D Dam break – Free surface flow
                             The constant directory
        • g
        • transportProperties
        • momentumTransport
                                                                               151
                         3D Dam break – Free surface flow
                                               The g dictionary file
                                                                                                             152
                             3D Dam break – Free surface flow
                             The transportProperties dictionary file
             Primary phase
                                                                                                                 153
                    3D Dam break – Free surface flow
                     The momentumTransport dictionary file
• In this dictionary file we select what model we would like to use (laminar or
  turbulent).
• This dictionary is compulsory.
• In this case we use a RANS turbulence model (kEpsilon).
        17    simulationType         RAS;
        18
        19    RAS
        20    {
        21          RASModel kEpsilon;
        22
        23          turbulence on;
        24
        25          printCoeffs on;
        26    }
                                                                                  154
                   3D Dam break – Free surface flow
                                  The 0 directory
• In this directory, we will find the dictionary files that contain the boundary and
  initial conditions for all the primitive variables.
• As we are solving the incompressible RANS Navier-Stokes equations using
  the VOF method, we will find the following field files:
                                                                                  155
                              3D Dam break – Free surface flow
                                             The file 0/alpha.water
17   dimensions      [0 0 0 0 0 0 0];
18                                                     •   This file contains the boundary and initial conditions
19
20
     internalField   uniform 0;                            for the non-dimensional scalar field alpha.water
21   boundaryField
22   {                                                 •   This file is named alpha.water, because the
23
24
         front
         {
                                                           primary phase is water (we defined the primary
25           type           zeroGradient;                  phase in the transportProperties dictionary).
26       }
27
28
         back
         {
                                                       •   Initially, this field is initialized as 0 in the whole
29           type           zeroGradient;                  domain (line 19). This means that there is no water in
30       }
31       left                                              the domain at time 0. Later, we will initialize the
32
33
         {
             type           zeroGradient;
                                                           water column and this file will be overwritten with a
34       }                                                 non-uniform field for the internalField.
35       right
36
37
         {
             type           zeroGradient;
                                                       •   For the front, back, left, right, bottom and
38       }                                                 stlSurface patches we are using a zeroGradient
39       bottom
40       {                                                 boundary condition (we are just extrapolating the
41           type           zeroGradient;                  internal values to the boundary face).
42       }
43       top
44       {                                             •   For the top patch we are using an inletOutlet
45
46
             type
             inletValue
                            inletOutlet;
                            uniform 0;
                                                           boundary condition. This boundary condition avoids
47           value          uniform 0;                     backflow into the domain. If the flow is going out it
48       }
49       stlSurface                                        will use zeroGradient and if the flow is coming back
50       {                                                 it will assign the value set in the keyword inletValue
51           type            zeroGradient;
52       }                                                 (line 46).
53
54   }
                                                                                                                156
                                3D Dam break – Free surface flow
                                                   The file 0/p_rgh
17   dimensions        [1 -1 -2 0 0 0 0];
18                                                        •   This file contains the boundary and initial conditions
19   internalField     uniform 0;
20                                                            for the dimensional scalar field p_rgh. The
21
22
     boundaryField
     {
                                                              dimensions of this field are given in Pascal (line 17)
23       front
24       {                                                •   This scalar field contains the value of the static
25
26
             type
             value
                              fixedFluxPressure;
                              uniform 0;
                                                              pressure field minus the hydrostatic component.
27       }
28       back                                             •   This field is initialized as 0 in the whole domain (line
33       left
                                                              19).
38       right                                            •   For the front, back, left, right, bottom and
43       bottom
                                                              stlSurface patches we are using the
                                                              fixedFluxPressure boundary condition (refer to the
48       top
49       {                                                    source code or doxygen documentation to know
50
51
               type
               p0
                              totalPressure;
                              uniform 0;
                                                              more about this boundary condition).
52             U              U;
53             phi            phi;                        •   For the top patch we are using the totalPressure
54
55
               rho
               psi
                              rho;
                              none;
                                                              boundary condition (refer to the source code or
56             gamma          1;                              doxygen documentation to know more about this
57             value          uniform 0;
58       }                                                    boundary condition).
59       stlSurface
60       {
61           type             fixedFluxPressure;
62           value            uniform 0;
63       }
64
65   }
                                                                                                                    157
                                3D Dam break – Free surface flow
                                                             The file 0/U
17   dimensions        [0 -1 -1 0 0 0 0];
18                                                                •   This file contains the boundary and initial conditions
19   internalField     uniform (0 0 0);
20                                                                    for the dimensional vector field U.
21   boundaryField
22   {                                                            •   We are using uniform initial conditions and the
23       front
24       {                                                            numerical value is (0 0 0) (keyword internalField in
25
26
             type
             value
                              fixedValue;
                              uniform (0 0 0);
                                                                      line 19).
27       }
28       back                                                     •   The front, back, left, right, bottom and stlSurface
33       left
                                                                      patches are no-slip walls, therefore we impose a
                                                                      fixedValue boundary condition with a value of (0 0 0)
38       right
                                                                      at the wall.
43       bottom
                                                                  •   For the top patch we are using the
48       top
49       {                                                            pressureInlterOutletVelocity boundary condition
50
51
               type
               value
                              pressureInletOutletVelocity;
                              uniform (0 0 0);
                                                                      (refer to the source code or doxygen documentation
52       }                                                            to know more about this boundary condition).
53       stlSurface
54       {
55           type             fixedValue;
56           value            uniform (0 0 0);
57       }
58
59   }
                                                                                                                           158
                               3D Dam break – Free surface flow
                                                       The file 0/k
17   dimensions       [0 2 -2 0 0 0 0];
18                                                          •   This file contains the boundary and initial conditions
19   internalField    uniform 0.1;
20                                                              for the dimensional scalar field k.
21   boundaryField
22   {                                                      •   This scalar (turbulent kinetic energy), is related to the
23       “(front|back|left|right|bottom|stlSurface)”
24       {                                                      turbulence model.
25           type            kqRWallFunction;
26           value           $internalField;                •   This field is initialized as 0.1 in the whole domain,
27       }
28                                                              and all the boundary patches take the same value
29
30
         top
         {
                                                                ($internalField).
31             type          inletOutlet;
32             inletValue    $internalField;                •   For the front, back, left, right, bottom and
33
34       }
               value         $internalField;
                                                                stlSurface patches we are using the
35                                                              kqRWallFunction boundary condition, which applies
36   }
                                                                a wall function at the walls (refer to the source code
                                                                or doxygen documentation to know more about this
                                                                boundary condition).
                                                            •   For the top patch we are using the inletOutlet
                                                                boundary condition, this boundary condition handles
                                                                backflow (refer to the source code or doxygen
                                                                documentation to know more about this boundary
                                                                condition).
                                                            •   We will deal with turbulence modeling later.
                                                                                                                        159
                               3D Dam break – Free surface flow
                                                       The file 0/epsilon
17   dimensions       [0 2 -3 0 0 0 0];
18                                                             •   This file contains the boundary and initial conditions
19   internalField    uniform 0.1;
20                                                                 for the dimensional scalar field epsilon.
21   boundaryField
22   {                                                         •   This scalar (rate of dissipation of turbulence energy),
23       “(front|back|left|right|bottom|stlSurface)”
24       {                                                         is related to the turbulence model.
25           type            epsilonWallFunction;
26           value           $internalField;                   •   This field is initialized as 0.1 in the whole domain,
27       }
28                                                                 and all the boundary patches take the same value
29
30
         top
         {
                                                                   ($internalField).
31             type          inletOutlet;
32             inletValue    $internalField;                   •   For the front, back, left, right, bottom and
33
34       }
               value         $internalField;
                                                                   stlSurface patches we are using the
35                                                                 epsilonWallFunction boundary condition, which
36   }
                                                                   applies a wall function at the walls (refer to the
                                                                   source code or doxygen documentation to know
                                                                   more about this boundary condition).
                                                               •   For the top patch we are using the inletOutlet
                                                                   boundary condition, this boundary condition handles
                                                                   backflow (refer to the source code or doxygen
                                                                   documentation to know more about this boundary
                                                                   condition).
                                                               •   We will deal with turbulence modeling later.
                                                                                                                           160
                                3D Dam break – Free surface flow
                                                       The file 0/nut
17   dimensions        [0 2 -1 0 0 0 0];
18                                                           •   This file contains the boundary and initial conditions
19   internalField     uniform 0;
20                                                               for the dimensional scalar field nut.
21   boundaryField
22   {                                                       •   This scalar (turbulent viscosity), is related to the
23       “(front|back|left|right|bottom|stlSurface)”
24       {                                                       turbulence model.
25           type            nutkWallFunction;
26           value           $internalField;                 •   This field is initialized as 0 in the whole domain, and
27       }
28                                                               all the boundary patches take the same value
29
30
         top
         {
                                                                 ($internalField).
31             type           calculated;
32             value          $internalField;;               •   For the front, back, left, right, bottom and
33
34
         }
                                                                 stlSurface patches we are using the
35   }                                                           nutkWallFunction boundary condition, which applies
                                                                 a wall function at the walls (refer to the source code
                                                                 or doxygen documentation to know more about this
                                                                 boundary condition).
                                                             •   For the top patch we are using the calculated
                                                                 boundary condition, this boundary condition
                                                                 computes the value of nut from k and epsilon (refer to
                                                                 the source code or doxygen documentation to know
                                                                 more about this boundary condition).
                                                             •   We will deal with turbulence modeling later.
                                                                                                                        161
                  3D Dam break – Free surface flow
                            The system directory
                                                                                162
                                 3D Dam break – Free surface flow
                                           The controlDict dictionary
                                                  • This case starts from time 0 (startTime), and it will run up to 8
17   application      interFoam;                    seconds (endTime).
18
19
20
     startFrom        startTime;
                                                  • The initial time step of the simulation is 0.0001 seconds
21   startTime        0;                            (deltaT).
22
23
24
     stopAt           endTime;
                                                  • It will write the solution every 0.02 seconds (writeInterval) of
25   endTime          8;                            simulation time (runTime). It will automatically adjust the time
26
27   deltaT           0.0001;                       step (adjustableRunTime), in order to save the solution at the
28
29   writeControl     adjustableRunTime;
                                                    precise write interval.
30
31   writeInterval    0.02;                       • It will keep all the solution directories (purgeWrite).
32
33   purgeWrite       0;                          • It will save the solution in ascii format (writeFormat).
34
35   writeFormat      ascii;
36                                                • The write precision is 8 digits (writePrecision). It will only save
37
38
     writePrecision   8;                            eight digits in the output files.
39   writeCompression uncompressed;
40                                                • And as the option runTimeModifiable is on, we can modify all
41
42
     timeFormat       general;                      these entries while we are running the simulation.
43   timePrecision    8;
44                                                • In line 47 we turn on the option adjustTimeStep. This option
45
46
     runTimeModifiable yes;
                                                    will automatically adjust the time step to achieve the maximum
47   adjustTimeStep   yes;                          desired courant number (lines 49-50). We also set a maximum
48
49   maxCo            1.0;                          time step in line 51.
50   maxAlphaCo       0.5;
51   maxDeltaT        0.01;                       • Remember, the first time step of the simulation is done using
                                                    the value set in line 27 and then it is automatically scaled to
                                                    achieve the desired maximum values (lines 49-51).
                                                                                                                      163
                               3D Dam break – Free surface flow
                                           The controlDict dictionary
144 };
                                                                                                                           164
                                   3D Dam break – Free surface flow
                                             The controlDict dictionary
144 };
                                                                                                                             165
                                3D Dam break – Free surface flow
                                         The controlDict dictionary
144 };
                                                   Sampling locations
                                                   (probeLocations)
                                                                                                                166
                             3D Dam break – Free surface flow
                                         The controlDict dictionary
                                                                                                                             167
                                3D Dam break – Free surface flow
                                               The fvSchemes dictionary
17   ddtSchemes                                                    • In this case, for time discretization (ddtSchemes) we are using the
18   {
19       default           Euler;                                    Euler method.
21   }
22
                                                                   • For gradient discretization (gradSchemes) we are using the Gauss
23   gradSchemes                                                     linear as the default method and slope limiters (cellLimited) for the
24   {                                                               velocity gradient or grad(U).
25       default           Gauss linear;
26       grad(U)           cellLimited Gauss linear 1;             • For the discretization of the convective terms (divSchemes) we are
27   }
28
                                                                     using linearUpwindV interpolation method for the term
29   divSchemes                                                      div(rhoPhi,U).
30   {
31       div(rhoPhi,U)    Gauss linearUpwindV grad(U);             • For the term div(phi,alpha) we are using interfaceCompression
                                                                     vanLeer interpolation scheme.
33       div(phi,alpha)    Gauss interfaceCompression vanLeer 1;
                                                                          • This is an interface compression corrected scheme used to
39       div(phi,k) Gauss upwind;                                           maintain sharp interfaces in VOF simulations.
40       div(phi,epsilon) Gauss upwind;
41       div(((rho*nuEff)*dev2(T(grad(U))))) Gauss linear;                • The coefficient defines the degree of compression, where 1 is
42   }
43
                                                                            suitable for most VOF applications.
44   laplacianSchemes                                              • For the terms div(phi,k) and div(phi,epsilon) we are using upwind
45   {
46       default           Gauss linear corrected;                   (these terms are related to the turbulence modeling).
47   }
48
                                                                   • For the term div(((rho*nuEff)*dev2(T(grad(U))))) we are using
49   interpolationSchemes                                            linear interpolation (this term is related to the turbulence modeling).
50   {
51       default          linear;                                  • For the discretization of the Laplacian (laplacianSchemes and
52   }                                                               snGradSchemes) we are using the Gauss linear corrected method
53
54   snGradSchemes                                                 • In overall, this method is second order accurate but a little bit
55   {                                                               diffusive. Remember, at the end of the day we want a solution that is
56       default           corrected;
57   }                                                               second order accurate.
                                                                                                                                          168
                              3D Dam break – Free surface flow
                                           The fvSolution dictionary
                                                                                                                     169
                               3D Dam break – Free surface flow
                                           The fvSolution dictionary
                                                                                                                   170
                               3D Dam break – Free surface flow
                                        The fvSolution dictionary
                                                    • Be careful not use too low values as you will loose time
                                                      accuracy.
                                                    • If you want to disable under-relaxation, comment out
                                                      these lines.
                                               • The option momentumPredictor (line 85), is recommended for
                                                 highly convective flows.
                                                                                                                 171
                   3D Dam break – Free surface flow
                              The system directory
• In the system directory you will find the following optional dictionary files:
        • decomposeParDict
        • setFieldsDict
                                                                                   172
                             3D Dam break – Free surface flow
                                       The setFieldsDict dictionary
                                                     •     This dictionary file is located in the directory system.
                                                     •     In lines 17-20 we set the default value to be 0 in the whole
17   defaultFieldValues                                    domain (no water).
18   (
19
20   );
         volScalarFieldValue alpha.water 0
                                                     •     In lines 22-32, we initialize a rectangular region (box)
21                                                         containing water (alpha.water 1).
22   regions
23
24
     (
         boxToCell
                                                     •     In this case, setFields will look for the dictionary file
25       {                                                 alpha.water and it will overwrite the original values
26           box (1.992 -10 0) (5 10 0.55);
27           fieldValues                                   according to the regions defined in setFieldsDict.
28           (
29               volScalarFieldValue alpha.water 1   •     We initialize the water phase because is the primary phase in
30           );
31       }                                                 the dictionary transportProperties.
32   );
                                                     •     If you are interested in initializing the vector field U, you can
                                                           proceed as follows volVectorFieldValue U (0 0 0)
                                                         Air
                                                         alpha.water = 0
                                                                                                Water
                                                                                                alpha.water = 1
                                                                                                 boxToCell region
                                                                                                                           173
                           3D Dam break – Free surface flow
                                The decomposeParDict dictionary
•   This dictionary file is located in the directory system.
•   This dictionary is used to decompose the domain in order to run in parallel.
•   The keyword numberOfSubdomains (line 17) is used to set the number of cores we want to use in the
    parallel simulation.
•   In this dictionary we also set the decomposition method (line 19).
•   Most of the times the scotch method is fine.
•   In this case we set the numberOfSubdomains to 4, therefore we will run in parallel using 4 cores.
                    17        numberOfSubdomains 4;
                    18
                    19        method scotch;
                    20
•   When you run in parallel, the solution is saved in the directories processorN, where N stands for processor
    number. In this case you will find the following directories with the decomposed mesh and solution:
    processor0, processor1, processor2, and processor3.
                                                                                                              174
                   3D Dam break – Free surface flow
   1.   $> foamCleanTutorials
   2.   $> rm –rf 0
   3.   $> blockMesh
   4.   $> surfaceFeatures
   5.   $> snappyHexMesh -overwrite
   6.   $> createPatch -dict system/createPatchDict.0 -overwrite
   7.   $> createPatch -dict system/createPatchDict.1 -overwrite
   8.   $> checkMesh
   9.   $> paraFoam
                                                                                  175
                    3D Dam break – Free surface flow
   1.   $> rm –rf 0
   2.   $> cp –r 0_org 0
   3.   $> setFields
   4.   $> paraFoam
   5.   $> decomposePar
   6.   $> mpirun –np 4 interFoam –parallel | tee log.interFoam
   7.   $> reconstructPar
   8.   $> paraFoam
                                                                      176
                     3D Dam break – Free surface flow
                                                                                             177
                        3D Dam break – Free surface flow
• To plot the sampled data using gnuplot you can proceed as follows. To enter to the
  gnuplot prompt type in the terminal:
1. $> gnuplot
                                                                            179
                                3D Dam break – Free surface flow
           2. Select alpha.water in
           the Active Variable drop-
           down menu
                                                                 Air                              Water
                                                                 alpha.water = 0                  alpha.water = 1
                                                             Interface
                                                             alpha.water = 0.5
                                                                                                                 181
                                   3D Dam break – Free surface flow
4. Press apply
                                                                                                             182
                                    3D Dam break – Free surface flow
4. Press apply
                                                                                                                183
                         3D Dam break – Free surface flow
                                                 Exercises
•   Instead of using the boundary condition totalPressure and pressureInletOutletVelocity for the patch top, try
    to use zeroGradient. Do you get the same results? Any comments?
    (Hint: this combination of boundary conditions might give you an error, if so, read carefully the screen
    and try to find a fix, you can start by looking at the file fvSolution)
•   Instead of using the boundary condition fixedFluxPressure for the walls, try to use zeroGradient. Do you get
    the same results? Any comments?
•   Run the simulation in a close domain. Does the volume integral of alpha.water remains the same? Why the
    value is not constant when the domain is open?
•   Use a functionObject to measure the average pressure on the obstacle.
•   How many initialization methods are there available in the dictionary setFieldsDict?
    (Hint: use the banana method)
•   Run the simulation using Gauss upwind instead of Gauss vanLeer or Gauss interfaceCompression
    vanLeer 1 for the term div(phi,alpha) (fvSchemes). Do you get the same quantitative results?
                                                                                                              184
                           3D Dam break – Free surface flow
                                                    Exercises
•   Run a numerical experiment for cAlpha equal to 0, 1, and 2. Do you see any difference in the solution? What
    about computing time?
•   Use the solver GAMG instead of using the solver PCG for the variable p_rgh. Do you see any difference on
    the solution or computing time?
•   Increase the number of nOuterCorrector to 2 and study the output screen. What difference do you see?
•   Turn off the MULES corrector (MULESCorr). Do you see any difference on the solution or computing time?
•   If you set the gravity vector to (0 0 0), what do you think will happen?
•   Try to break the solver and identify the cause of the error. You are free to try any kind of setup.
                                                                                                             185
                       Roadmap
                                                           186
Flow past a cylinder – From laminar to turbulent flow
                                                               187
Flow past a cylinder – From laminar to turbulent flow
             Flow around a cylinder – 10 < Re < 2 000 000
                Incompressible and compressible flow
                                                                                         188
Flow past a cylinder – From laminar to turbulent flow
                                            Workflow of the case
                                                    blockMesh
                                                        Or
                                                fluentMeshToFoam
                                                     icoFoam
                   NOTE:                            pisoFoam
     One single mesh can be used with all
             solvers and utilities                 pimpleFoam
                                                 pimpleDyMFoam
                                                   simpleFoam
                                                                               functionObjects
                                                 rhoPimpleFoam
                                                    interFoam
                                                    sonicFoam
                                                  potentialFoam
                                                    mapFields
                                                              postProcessing
                                                                  utilities
sampling paraview
                                                                                                 189
Flow past a cylinder – From laminar to turbulent flow
Strouhal number
                                                                                                        190
       Flow past a cylinder – From laminar to turbulent flow
 Some experimental (E) and numerical (N) results of the flow past a circular
                cylinder at various Reynolds numbers
[1] D. Tritton. Experiments on the flow past a circular cylinder at low Reynolds numbers. Journal of Fluid Mechanics, 6:547-567, 1959.
[2] M. Cuntanceau and R. Bouard. Experimental determination of the main features of the viscous flow in the wake of a circular cylinder in uniform translation. Part 1. Steady flow. Journal of Fluid
    Mechanics, 79:257-272, 1973.
[3] D. Rusell and Z. Wang. A cartesian grid method for modeling multiple moving objects in 2D incompressible viscous flow. Journal of Computational Physics, 191:177-205, 2003.
[4] D. Calhoun and Z. Wang. A cartesian grid method for solving the two-dimensional streamfunction-vorticity equations in irregular regions. Journal of Computational Physics. 176:231-275, 2002.
[5] T. Ye, R. Mittal, H. Udaykumar, and W. Shyy. An accurate cartesian grid method for viscous incompressible flows with complex immersed boundaries. Journal of Computational Physics,
    156:209-240, 1999.
[6] B. Fornberg. A numerical study of steady viscous flow past a circular cylinder. Journal of Fluid Mechanics, 98:819-855, 1980.
[7] J. Guerrero. Numerical simulation of the unsteady aerodynamics of flapping flight. PhD Thesis, University of Genoa, 2009.
                                                                                                                                                                                                 191
       Flow past a cylinder – From laminar to turbulent flow
 Some experimental (E) and numerical (N) results of the flow past a circular
                cylinder at various Reynolds numbers
[1] Russel and Wang (N) 1.38 ± 0.007 ± 0.322 1.29 ± 0.022 ± 0.50
[2] Calhoun and Wang (N) 1.35 ± 0.014 ± 0.30 1.17 ± 0.058 ± 0.67
[3] Braza et al. (N) 1.386± 0.015 ± 0.25 1.40 ± 0.05 ± 0.75
[4] Choi et al. (N) 1.34 ± 0.011 ± 0.315 1.36 ± 0.048 ± 0.64
[5] Liu et al. (N) 1.35 ± 0.012 ± 0.339 1.31 ± 0.049 ± 0.69
[1] D. Rusell and Z. Wang. A cartesian grid method for modeling multiple moving objects in 2D incompressible viscous flow. Journal of Computational Physics, 191:177-205, 2003.
[2] D. Calhoun and Z. Wang. A cartesian grid method for solving the two-dimensional streamfunction-vorticity equations in irregular regions. Journal of Computational Physics. 176:231-275, 2002.
[3] M. Braza, P. Chassaing, and H. Hinh. Numerical study and physical analysis of the pressure and velocity fields in the near wake of a circular cylinder. Journal of Fluid Mechanics, 165:79-130,
1986.
[4] J. Choi, R. Oberoi, J. Edwards, an J. Rosati. An immersed boundary method for complex incompressible flows. Journal of Computational Physics, 224:757-784, 2007.
[5] C. Liu, X. Zheng, and C. Sung. Preconditioned multigrid methods for unsteady incompressible flows. Journal of Computational Physics, 139:33-57, 1998.
[6] J. Guerrero. Numerical Simulation of the unsteady aerodynamics of flapping flight. PhD Thesis, University of Genoa, 2009.
                                                                                                                                                                                                192
Flow past a cylinder – From laminar to turbulent flow
            At the end of the day, you should get something like this
                                                                                                                                  193
Flow past a cylinder – From laminar to turbulent flow
    At the end of the day, you should get something like this
$PTOFC/101OF/vortex_shedding
•   In the case directory, you will find the README.FIRST file. In this file, you will find the general instructions of
    how to run the case. In this file, you might also find some additional comments.
•   You will also find a few additional files (or scripts) with the extension .sh, namely, run_all.sh,
    run_mesh.sh, run_sampling.sh, run_solver.sh, and so on. These files can be used to run the case
    automatically by typing in the terminal, for example, sh run_solver.
•   We highly recommend you to open the README.FIRST file and type the commands in the terminal, in this
    way, you will get used with the command line interface and OpenFOAM® commands.
•   If you are already comfortable with OpenFOAM®, use the automatic scripts to run the cases.
                                                                                                                      195
   Flow past a cylinder – From laminar to turbulent flow
                              What are we going to do?
• We will use this case to learn how to use different solvers and utilities.
• Remember, different solvers have different input dictionaries.
• We will learn how to convert the mesh from a third-party software.
• We will learn how to use setFields to initialize the flow field and accelerate the
  convergence.
• We will learn how to map a solution from a coarse mesh to a fine mesh.
• We will learn how to setup a compressible solver.
• We will learn how to setup a turbulence case.
• We will use gnuplot to plot and compute the mean values of the lift and drag
  coefficients.
• We will visualize unsteady data.
                                                                                       196
   Flow past a cylinder – From laminar to turbulent flow
                                    Running the case
• Let us first convert the mesh from a third-party format (Fluent format).
• You will find this tutorial in the directory $PTOFC/101OF/vortex_shedding/c2
• In the terminal window type:
   1.   $> foamCleanTutorials
   2.   $>   fluent3DMeshToFoam ../../../meshes_and_geometries/vortex_shedding/ascii.msh
   3.   $> checkMesh
   4.   $> paraFoam
• In step 2, we convert the mesh from Fluent format to OpenFOAM® format. Have in
  mind that the Fluent mesh must be in ascii format.
• If we try to open the mesh using paraFoam (step 4), it will crash. Can you tell what is
  the problem by just reading the screen?
                                                                                           197
   Flow past a cylinder – From laminar to turbulent flow
                                            Running the case
• To avoid this problem, type in the terminal,
• Basically, the problem is related to the names and type of the patches in the file
  boundary and the boundary conditions (U, p). Notice that OpenFOAM® is telling you
  what and where is the error.
FOAM exiting
                                                                                                                   198
   Flow past a cylinder – From laminar to turbulent flow
• Remember, when converting meshes the name and type of the patches are not
  always set as you would like, so it is always a good idea to take a look at the file
  boundary and modify it according to your needs.
• Let us modify the boundary dictionary file.
• In this case, we would like to setup the following numerical type boundary
  conditions.
                                                                                         199
Flow past a cylinder – From laminar to turbulent flow
                                       The boundary dictionary file
                                                                                                      200
Flow past a cylinder – From laminar to turbulent flow
                                     The boundary dictionary file
                                                                                                     201
   Flow past a cylinder – From laminar to turbulent flow
• At this point, check that the name and type of the base type boundary conditions
  and numerical type boundary conditions are consistent. If everything is ok, we are
  ready to go.
• Do not forget to explore the rest of the dictionary files, namely:
         • 0/p         (p is defined as relative pressure)
         • 0/U
         • constant/transportProperties
         • system/controlDict
         • system/fvSchemes
         • system/fvSolution
• Reminder:
    • The diameter of the cylinder is 2.0 m.
    • And we are targeting for a Re = 200.
                                                                                       202
   Flow past a cylinder – From laminar to turbulent flow
                                                Running the case
• You will find this tutorial in the directory $PTOFC/101OF/vortex_shedding/c2
• In the folder c1 you will find the same setup, but to generate the mesh we use
  blockMesh (the mesh is identical).
• To run this case, in the terminal window type:
5. $> paraFoam
                                                                                   203
   Flow past a cylinder – From laminar to turbulent flow
                                   Running the case
• In step 1 we use the utility renumberMesh to make the linear system more diagonal
  dominant, this will speed-up the linear solvers. This is inexpensive (even for large
  meshes), therefore is highly recommended to always do it.
• In step 2 we run the simulation and save the log file. Notice that we are sending the
  job to background.
• In step 3 we use pyFoamPlotWatcher.py to plot the residuals on-the-fly. As the
  job is running in background, we can launch this utility in the same terminal tab.
• In step 4 we use the gnuplot script scripts0/plot_coeffs to plot the force
  coefficients on-the-fly. Besides monitoring the residuals, is always a good idea to
  monitor a quantity of interest. Feel free to take a look at the script and to reuse it.
• The force coefficients are computed using functionObjects.
• After the simulation is over, we use paraFoam to visualize the results. Remember to
  use the VCR Controls to animate the solution.
• In the folder c1 you will find the same setup, but to generate the mesh we use
  blockMesh (the mesh is identical).
                                                                                            204
                                    Flow past a cylinder – From laminar to turbulent flow
    • At this point try to use the following utilities. In the terminal type:
       • $> postProcess –func vorticity –noZero
                                      This utility will compute and write the vorticity field. The –noZero option means do not compute the vorticity field for the
                                      solution in the directory 0. If you do not add the –noZero option, it will compute and write the vorticity field for all the
                                      saved solutions, including 0
                                    • $> postprocess –func 'grad(U)' –latestTime
                                      This utility will compute and write the velocity gradient or grad(U) in the whole domain (including at the walls). The
                                      –latestTime option means compute the velocity gradient only for the last saved solution.
                                    • $> postprocess –func 'grad(p)'
                                      This utility will compute and write the pressure gradient or grad(U) in the whole domain (including at the walls).
                                    • $> foamToVTK –time 50:300
                                      This utility will convert the saved solution from OpenFOAM® format to VTK format. The –time 50:300 option means
                                      convert the solution to VTK format only for the time directories 50 to 300
                                      This utility will compute and write the divergence of the velocity field or grad(U) in the whole domain (including at the
                                      walls).
                                    • $> pisoFoam -postProcess -func CourantNo
                                      This utility will compute and write the Courant number. This utility needs to access the solver database for the physical
                                      properties and additional quantities; therefore we need to tell what solver we are using. As the solver icoFoam does not
                                      accept the option –postProcess, we can use the solver pisoFoam instead. Remember, icoFoam is a fully laminar
                                      solver and pisoFoam is a laminar/turbulent solver.
                                    • $> pisoFoam -postProcess -func wallShearStress
                                      This utility will compute and write the wall shear stresses at the walls. As no arguments are given, it will save the wall
                                      shear stresses for all time steps.
                                                                                                                                                                   205
    Flow past a cylinder – From laminar to turbulent flow
                               Non-uniform field initialization
•   In the previous case, it took about 150 seconds of simulation time to onset the instability.
•   If you are not interested in the initial transient or if you want to speed-up the computation, you
    can add a perturbation in order to trigger the onset of the instability.
•   Let us use the utility setFields to initialize a non-uniform flow.
•   This case is already setup in the directory ,
           $PTOFC/101OF/vortex_shedding/c3
•   As you saw in the previous example, icoFoam is a very basic solver that does not have access
    to all the advanced modeling or postprocessing capabilities that comes with OpenFOAM®.
•   Therefore, instead of using icoFoam we will use pisoFoam (or pimpleFoam) from now on.
•   To run the solver pisoFoam (or pimpleFoam) starting from the directory structure of an
    icoFoam case, you will need to add the followings modifications:
     •   Add the file momentumTransport in the directory constant.
     •   Add the transportModel to be used in the file constant/transportProperties.
     •   Add the entry div((nuEff*dev2(T(grad(U))))) Gauss linear; to the dictionary
         system/fvSchemes in the section divSchemes (this entry is related to the Reynodls
         stresses).
                                                                                                         206
      Flow past a cylinder – From laminar to turbulent flow
• Let us run the same case but using a non-uniform field
                                           The setFieldsDict dictionary
                                                               •   This dictionary file is located in the directory system.
 17    defaultFieldValues                                      •   In lines 17-20 we set the default value of the velocity vector
 18    (
 19        volVectorFieldValue U (1 0 0)                           to be (0 0 0) in the whole domain.
 20    );
 21                                                            •   In lines 24-31, we initialize a rectangular region (box) just
 22    regions
 23    (                                                           behind the cylinder with a velocity vector equal to (0.98480
 24        boxToCell                                               0.17364 0)
 25        {
 26            box (0 -100 -100) (100 100 100);
 27            fieldValues                                     •   In this case, setFields will look for the dictionary file U
 28
 29
               (
                   volVectorFieldValue U (0.98480 0.17364 0)
                                                                   and it will overwrite the original values according to the
 30            );                                                  regions defined in setFieldsDict.
 31        }
 32    );
boxToCell region
                                                                                                 U (0.98480 0.17364 0)
                                                                                   U (1 0 0)
                                                                                                                                     207
    Flow past a cylinder – From laminar to turbulent flow
•   Let us run the same case but using a non-uniform field.
•   You will find this tutorial in the directory $PTOFC/101OF/vortex_shedding/c3
•   Feel free to use the Fluent mesh or the mesh generated with blockMesh. Hereafter, we will
    use blockMesh.
•   To run this case, in the terminal window type:
    1.    $> foamCleanTutorials
    2.    $> blockMesh
    3.    $> rm –rf 0 > /dev/null 2>&1
    4.    $> cp –r 0_org/ 0
    5.    $> setFields
    6.    $> renumberMesh -overwrite
    7.    $> pisoFoam | tee log.solver
          $> pyFoamPlotWatcher.py log.pisofoam
    8.
          You will need to launch this script in a different terminal
                                                                                        209
   Flow past a cylinder – From laminar to turbulent flow
           Does non-uniform field initialization make a difference?
• A picture is worth a thousand words. No need to tell you yes, even if the solutions are
  slightly different.
• This bring us to the next subject, for how long should we run the simulation?
                                                                                       210
Flow past a cylinder – From laminar to turbulent flow
          For how long should run the simulation?
                                                                                 211
Flow past a cylinder – From laminar to turbulent flow
                What about the residuals?
                                                                                 212
      Flow past a cylinder – From laminar to turbulent flow
                                        How to compute force coefficients
                                                                                                                 213
      Flow past a cylinder – From laminar to turbulent flow
 Can we compute basic statistics of the force coefficients using gnuplot?
• Yes we can. Enter the gnuplot prompt and type:
 4.    gnuplot> exit
       To exit gnuplot
                                                                                                                                              214
     Flow past a cylinder – From laminar to turbulent flow
                                               On the solution accuracy
17    ddtSchemes
                                                          • At the end of the day we want a solution that is second order
18    {                                                     accurate.
20      default          backward;
22
23
      }
                                                          • We define the discretization schemes (and therefore the
24    gradSchemes                                           accuracy) in the dictionary fvSchemes.
25    {
29
35    }
          default           cellLimited leastSquares 1;
                                                          • In this case, for time discretization (ddtSchemes) we are
36                                                          using the backward method.
37    divSchemes
38
39
      {
          default         none;
                                                          • For gradient discretization (gradSchemes) we are using the
43        div(phi,U)      Gauss linearUpwindV default;      leastSquares method with slope limiters (cellLimited) for all
48        div((nuEff*dev2(T(grad(U))))) Gauss linear;
49    }                                                     terms (default option).
50
51    laplacianSchemes                                    • Sometimes adding a gradient limiter to the pressure gradient
52    {
53        default         Gauss linear limited 1;           or grad(p) can be too diffusive, so it is better not to use
54
55
      }
                                                            gradient limiters for grad(p), e.g., grad(p) leastSquares.
56    interpolationSchemes
57    {                                                   • For the discretization of the convective terms (divSchemes)
58
59    }
          default         linear;
                                                            we are using linearUpwindV interpolation method for the
60                                                          term div(rho,U).
61    snGradSchemes
62
63
      {
          default         limited 1;
                                                          • For the discretization of the Laplacian (laplacianSchemes
64    }                                                     and snGradSchemes) we are using the Gauss linear
                                                            limited 1 method
                                                          • In overall, this method is second order accurate (this is what
                                                            we want).
                                                                                                                        215
     Flow past a cylinder – From laminar to turbulent flow
                                 On the solution tolerance and linear solvers
17    solvers
                                                  • We define the solution tolerance and linear solvers in the
18    {                                             dictionary fvSolution.
31        p
32
33
          {
                solver           GAMG;
                                                  • To solve the pressure (p) we are using the GAMG method
34              tolerance        1e-6;              with an absolute tolerance of 1e-6 and a relative tolerance
35              relTol           0;
36              smoother         GaussSeidel;       relTol of 0.01.
37              nPreSweeps       0;
38              nPostSweeps      2;               • The entry pFinal refers to the final correction of the PISO
39              cacheAgglomeration on;
40              agglomerator     faceAreaPair;      loop. It is possible to use a tighter convergence criteria only
41
42
                nCellsInCoarsestLevel 100;
                mergeLevels      1;
                                                    in the last iteration.
43        }
44                                                • To solve U we are using the solver PBiCGStab and the DILU
45
46
          pFinal
          {
                                                    preconditioner, with an absolute tolerance of 1e-8 and a
47            $p;                                   relative tolerance relTol of 0 (the solver will stop iterating
48            relTol             0;
49        }                                         when it meets any of the conditions).
50
51        U                                       • Solving for the velocity is relative inexpensive, whereas
52        {
53              solver           PBiCGStab;         solving for the pressure is expensive.
54              preconditioner   DILU;
55              tolerance        1e-08;           • The PISO sub-dictionary contains entries related to the
56              relTol           0;
57        }                                         pressure-velocity coupling (in this case the PISO method).
69
70
      }
                                                    Hereafter we are doing two PISO correctors (nCorrectors)
71    PISO                                          and two non-orthogonal corrections
72    {
73        nCorrectors     2;                        (nNonOrthogonalCorrectors).
74        nNonOrthogonalCorrectors 2;
77    }
                                                                                                                 216
     Flow past a cylinder – From laminar to turbulent flow
                                     On the runtime parameters
17    application      pisoFoam;
                                             • This case starts from the latest saved solution (startFrom).
18
20    startFrom        latestTime;           • In this case as there are no saved solutions, it will start from
21
22    startTime        0;
                                               0 (startTime).
23
24    stopAt           endTime;              • It will run up to 350 seconds (endTime).
26
27    endTime          350;                  • The time step of the simulation is 0.05 seconds (deltaT). The
28
29    deltaT           0.05;                   time step has been chosen in such a way that the Courant
30
31    writeControl     runTime;
                                               number is less than 1
32
33    writeInterval    1;                    • It will write the solution every 1 second (writeInterval) of
34
35    purgeWrite       0;
                                               simulation time (runTime).
36
37    writeFormat      ascii;                • It will keep all the solution directories (purgeWrite).
38
39
40
      writePrecision   8;                    • It will save the solution in ascii format (writeFormat).
41    writeCompression off;
42                                           • The write precision is 8 digits (writePrecision).
43    timeFormat       general;
44                                           • And as the option runTimeModifiable is on, we can modify
45    timePrecision    6;
46                                             all these entries while we are running the simulation.
47    runTimeModifiable true;
                                                                                                              217
                   Flow past a cylinder – From laminar to turbulent flow
                                                                     The output screen
•                  This is the output screen of the pisoFoam solver.
    nCorrector 1
                   Time = 350
                                                                                      Courant number
                   Courant Number mean: 0.11299953 max: 0.87674198
                   DILUPBiCG: Solving for Ux, Initial residual = 0.0037946307, Final residual = 4.8324843e-09, No Iterations 3
                   DILUPBiCG: Solving for Uy, Initial residual = 0.011990022, Final residual = 5.8815028e-09, No Iterations 3
                   GAMG: Solving for p, Initial residual = 0.022175872, Final residual = 6.2680545e-07, No Iterations 14
                   GAMG: Solving for p, Initial residual = 0.0033723932, Final residual = 5.8494331e-07, No Iterations 8
                                                                                                                                     nNonOrthogonalCorrectors 2
                   GAMG: Solving for p, Initial residual = 0.0010074964, Final residual = 4.4726195e-07, No Iterations 7
                   time step continuity errors : sum local = 1.9569266e-11, global = -3.471923e-14, cumulative = -2.8708402e-10
                   GAMG: Solving for p, Initial residual = 0.0023505548, Final residual = 9.9222424e-07, No Iterations 8
                   GAMG: Solving for p, Initial residual = 0.00045248026, Final residual = 7.7250386e-07, No Iterations 6
                   GAMG: Solving for p, Initial residual = 0.00014664077, Final residual = 4.5825218e-07, No Iterations 5                      pFinal
                   time step continuity errors : sum local = 2.0062733e-11, global = 1.2592813e-13, cumulative = -2.8695809e-10
                   ExecutionTime = 746.46 s ClockTime = 807 s
                                                                                                                                                           218
    Flow past a cylinder – From laminar to turbulent flow
                Let us use a potential solver to find a quick solution
•   In this case we are going to use the potential solver potentialFoam (remember potential
    solvers are inviscid, irrotational and incompressible)
•   This solver is super fast, and it can be used to find a solution to be used as initial conditions
    (non-uniform field) for an incompressible solver.
•   A good initial condition will accelerate and improve the convergence rate.
•   This case is already setup in the directory
$PTOFC/101OF/vortex_shedding/c4
                                                                                                        219
   Flow past a cylinder – From laminar to turbulent flow
 Running the case – Let us use a potential solver to find a quick solution
   1.   $> foamCleanTutorials
   2.   $> blockMesh
   3.   $> rm –rf 0
   4.   $> cp –r 0_org 0
   5.   $> potentialFoam –noFunctionObjects –initialiseUBCs –writep -writePhi
6. $> paraFoam
                                                                                   220
   Flow past a cylinder – From laminar to turbulent flow
 Running the case – Let us use a potential solver to find a quick solution
• In step 2 we generate the mesh using blockMesh. The name and type of the
  patches are already set in the dictionary blockMeshDict so there is no need to
  modify the boundary file.
• In step 4 we copy the original files to the directory 0. We do this to keep a backup of
  the original files as they will be overwritten by the solver potentialFoam.
• In step 5 we run the solver. We use the option –noFunctionObjects to avoid
  conflicts with the functionobjects. The options –writep and –writePhi will write
  the pressure field and fluxes respectively.
• At this point, if you want to use this solution as initial conditions for an incompressible
  solver, just copy the files U and p into the start directory of the incompressible case
  you are looking to run. Have in mind that the meshes need to be the same.
• Be careful with the name and type of the boundary conditions, they should be same
  between the potential case and incompressible case.
                                                                                           221
   Flow past a cylinder – From laminar to turbulent flow
                                  Potential solution
• Using a potential solution as initial conditions is much better than using a uniform
  flow. It will speed up the solution and it will give you more stability.
• Finding a solution using the potential solver is inexpensive.
                                                                                         222
     Flow past a cylinder – From laminar to turbulent flow
                                                                The output screen
•    This is the output screen of the potentialFoam solver.
•    The output of this solver is also a good indication of the sensitivity of the mesh quality
     to gradients computation. If you see that the number of iterations are dropping
     iteration after iteration, it means that the mesh is fine.
•    If the number of iterations remain stalled, it means that the mesh is sensitive to
     gradients, so you should use non-orthogonal correction.
•    In this case we have a good mesh.
End
                                                                                                                                                         223
   Flow past a cylinder – From laminar to turbulent flow
          Let us map a solution from a coarse mesh to a finer mesh
• It is also possible to map the solution from a coarse mesh to a finer mesh (and all the
  way around).
• For instance, you can compute a full Navier-Stokes solution in a coarse mesh (fast
  solution), and then map it to a finer mesh.
• Let us map the solution from the potential solver to a finer mesh (if you want you can
  map the solution obtained using pisoFoam or icoFoam). To do this we will use the
  utility mapFields.
• This case is already setup in the directory
$PTOFC/101OF/vortex_shedding/c6
                                                                                       224
   Flow past a cylinder – From laminar to turbulent flow
  Running the case – Let us map a solution from a coarse mesh to a finer mesh
   1.   $> foamCleanTutorials
   2.   $> blockMesh
   3.   $> rm –rf 0
   4.   $> cp –r 0_org 0
   5.   $> mapfields ../c4 –consistent –noFunctionObjects –mapMethod cellPointInterpolate -sourceTime 0
6. $> paraFoam
                                                                                                     225
   Flow past a cylinder – From laminar to turbulent flow
  Running the case – Let us map a solution from a coarse mesh to a finer mesh
• In step 2 we generate a finer mesh using blockMesh. The name and type of the
  patches are already set in the dictionary blockMeshDict so there is no need to
  modify the boundary file.
• In step 4 we copy the original files to the directory 0. We do this to keep a backup of
  the original files as they will be overwritten by the utility mapFields.
• In step 5 we use the utility mapFields with the following options:
    • We copy the solution from the directory ../c4
    • The options –consistent is used when the domains and BCs are the same.
    • The option –noFunctionObjects is used to avoid conflicts with the
      functionObjects.
    • The option –mapMethod cellPointInterpolate defines the interpolation
      method.
    • The option -sourceTime 0 defines the time from which we want to interpolate
      the solution.
                                                                                        226
Flow past a cylinder – From laminar to turbulent flow
               The meshes and the mapped fields
mapFields
                                                          227
    Flow past a cylinder – From laminar to turbulent flow
                                              The output screen
•   This is the output screen of the mapFields utility.
• The utility mapFields, will try to interpolate all fields in the source directory.
• You can control the target time via the startFrom and startTime keywords in the
  controlDict dictionary file.
     Source: "/home/joegi/my_cases_course/OF8/101OF/vortex_shedding" "c5"                           Source case
     Target: "/home/joegi/my_cases_course/OF8/101OF/vortex_shedding" "c6"                           Target case
     Mapping method: cellPointInterpolate                    Interpolation method
Source mesh size: 9200 Target mesh size: 36800 Source and target mesh cell count
           interpolating Phi
           interpolating p                               Interpolated fields
           interpolating U
End
• Finally, after mapping the solution, you can run the solver in the usual way. The solver
  will use the mapped solution as initial conditions.                                   228
   Flow past a cylinder – From laminar to turbulent flow
                              Setting a turbulent case
• So far we have used laminar incompressible solvers.
• Let us do a turbulent simulation.
• When doing turbulent simulations, we need to choose the turbulence model, define
  the boundary and initial conditions for the turbulent quantities, and modify the
  fvSchemes and fvSolution dictionaries to take account for the new variables we
  are solving (the transported turbulent quantities).
• This case is already setup in the directory
$PTOFC/101OF/vortex_shedding/c14
                                                                                     229
  Flow past a cylinder – From laminar to turbulent flow
• The following dictionaries remain unchanged
        • system/blockMeshDict
        • constant/polyMesh/boundary
        • 0/p
        • 0/U
      16    transportModel    Newtonian;
      17
      19    nu                nu [ 0 2 -1 0 0 0 0 ] 0.0002;
• Reminder:
    • The diameter of the cylinder is 2.0 m.
    • And we are targeting for a Re = 10000.
                                                                              231
    Flow past a cylinder – From laminar to turbulent flow
                          The momentumTransport dictionary file
•   This dictionary file is located in the directory constant.
•   In this dictionary file we select what model we would like to use (laminar or turbulent).
•   In this case we are interested in modeling turbulence, therefore the dictionary is as follows
• If you want to know the models available use the banana method.
                                                                                                                232
     Flow past a cylinder – From laminar to turbulent flow
                                     The controlDict dictionary
17    application      pimpleFoam;
                                             • This case will start from the last saved solution (startFrom). If there is
18                                             no solution, the case will start from time 0 (startTime).
20    startFrom        latestTime;
21                                           • It will run up to 500 seconds (endTime).
22    startTime        0;
23                                           • The initial time step of the simulation is 0.001 seconds (deltaT).
24    stopAt           endTime;
25
26    endTime          500;
                                             • It will write the solution every 1 second (writeInterval) of simulation time
27                                             (runTime).
28    deltaT           0.001;
29                                           • It will keep all the solution directories (purgeWrite).
30    writeControl     runTime;
31                                           • It will save the solution in ascii format (writeFormat).
32    writeInterval    1;
33
34    purgeWrite       0;
                                             • The write precision is 8 digits (writePrecision).
35
36    writeFormat      ascii;                • And as the option runTimeModifiable is on, we can modify all these
37                                             entries while we are running the simulation.
38    writePrecision   8;
39                                           • In line 48 we turn on the option adjustTimeStep. This option will
40    writeCompression off;
41                                             automatically adjust the time step to achieve the maximum desired
42    timeFormat       general;                courant number maxCo (line 50).
43
44    timePrecision    6;                    • We also set a maximum time step maxDeltaT in line 51.
45
46    runTimeModifiable yes;                 • Remember, the first time-step of the simulation is done using the value
47
48    adjustTimeStep   yes;                    set in line 28 and then it is automatically scaled to achieve the desired
49                                             maximum values (lines 50-51).
50    maxCo            0.9;
51    maxDeltaT        0.1;                  • The feature adjustTimeStep is only present in the PIMPLE family
                                               solvers, but it can be added to any solver by modifying the source code.
                                                                                                                       233
     Flow past a cylinder – From laminar to turbulent flow
                                               The fvSchemes dictionary
                                                                                                                                       234
     Flow past a cylinder – From laminar to turbulent flow
                                             The fvSolution dictionary
17    solvers
                                                     • To solve the pressure (p) we are using the GAMG method, with an
18    {                                                absolute tolerance of 1e-6 and a relative tolerance relTol of 0.001.
31        p                                            Notice that we are fixing the number of minimum iterations (minIter).
32        {
33              solver           GAMG;
34              tolerance        1e-6;
                                                     • To solve the final pressure correction (pFinal) we are using the PCG
35              relTol           0.001;                method with the DIC preconditioner, with an absolute tolerance of 1e-6
36              smoother         GaussSeidel;          and a relative tolerance relTol of 0.
37              nPreSweeps       0;
38              nPostSweeps      2;
39              cacheAgglomeration on;
                                                     • Notice that we can use different methods between p and pFinal. In this
40              agglomerator     faceAreaPair;         case we are using a tighter tolerance for the last iteration.
41              nCellsInCoarsestLevel 100;
42              mergeLevels      1;                  • We are also fixing the number of minimum iterations (minIter). This
44              minIter        2;
45       }
                                                       entry is optional.
46
47       pFinal                                      • To solve U we are using the solver PBiCGStab with the DILU
48       {                                             preconditioner, an absolute tolerance of 1e-8 and a relative tolerance
49           solver          PCG;
50           preconditioner DIC;
                                                       relTol of 0. Notice that we are fixing the number of minimum iterations
51           tolerance       1e-06;                    (minIter).
52           relTol          0;
53           minIter        3;
54       }
55
56       U
57       {
58              solver          PBiCGStab;
59              preconditioner DILU;
60              tolerance       1e-08;
61              relTol          0;
62              minIter        3;
63       }
                                                                                                                               235
      Flow past a cylinder – From laminar to turbulent flow
                                               The fvSolution dictionary
17     solvers
                                                       • To solve UFinal we are using the solver PBiCGStab with an absolute
18     {                                                 tolerance of 1e-8 and a relative tolerance relTol of 0. Notice that we are
                                                         fixing the number of minimum iterations (minIter).
77        UFinal
78        {
79            solver              PBiCGStab;
                                                       • To solve omega and omegaFinal we are using the solver PBiCGStab
80            preconditioner      DILU;                  with an absolute tolerance of 1e-8 and a relative tolerance relTol of 0.
81            tolerance           1e-08;                 Notice that we are fixing the number of minimum iterations (minIter).
82            relTol              0;
83            minIter             3;
84        }
                                                       • To solve k we are using the solver PBiCGStab with an absolute
85                                                       tolerance of 1e-8 and a relative tolerance relTol of 0. Notice that we are
86        omega                                          fixing the number of minimum iterations (minIter).
87        {
88            solver              PBiCGStab;
89            preconditioner      DILU;
90            tolerance           1e-08;
91            relTol              0;
92            minIter             3;
93        }
94
95        omegaFinal
96        {
97            solver              PBiCGStab;
98            preconditioner      DILU;
99            tolerance           1e-08;
100           relTol              0;
101           minIter             3;
102       }
103
104       k
105       {
106              solver           PBiCGStab;
107              preconditioner   DILU;
108              tolerance        1e-08;
109              relTol           0;
110              minIter          3;
111       }
                                                                                                                               236
      Flow past a cylinder – From laminar to turbulent flow
                                              The fvSolution dictionary
113        kFinal
                                                      • To solve kFinal we are using the solver PBiCGStab with an absolute
114        {                                            tolerance of 1e-8 and a relative tolerance relTol of 0. Notice that we are
115            solver           PBiCGStab;              fixing the number of minimum iterations (minIter).
116            preconditioner   DILU;
117            tolerance        1e-08;
118            relTol           0;
                                                      • In lines 123-133 we setup the entries related to the pressure-velocity
119            minIter          3;                      coupling method used (PIMPLE in this case). Setting the keyword
120        }                                            nOuterCorrectors to 1 is equivalent to running using the PISO method.
121    }
122
123    PIMPLE
                                                      • To gain more stability we are using 1 outer correctors
124    {                                                (nOuterCorrectors), 3 inner correctors or PISO correctors
126             nOuterCorrectors 1;                     (nCorrectors), and 1 correction due to non-orthogonality
127             //nOuterCorrectors 2;
128                                                     (nNonOrthogonalCorrectors).
129             nCorrectors 3;
130             nNonOrthogonalCorrectors 1;           • Remember, adding corrections increase the computational cost.
133    }
134                                                   • In lines 135-147 we setup the under-relaxation factors used during the
135    relaxationFactors
136    {
                                                        outer corrections of the PIMPLE method.
137        fields
138        {                                                • The values defined correspond to the industry standard of the
139            p                0.3;                          SIMPLE method.
140        }
141        equations                                        • By using under-relaxation we ensure diagonal equality.
142        {
143            U                0.7;
144            k                0.7;
                                                            • Be careful not use too low values as you will loose time accuracy.
145            omega            0.7;
146        }                                                • If you want to disable under-relaxation, comment out these lines.
147    }
                                                                                                                              237
  Flow past a cylinder – From laminar to turbulent flow
• The following dictionaries are new
        • 0/k
        • 0/omega
        • 0/nut
  These are the field variables related to the closure equations of the turbulent
  model.
                                                                                 238
    Flow past a cylinder – From laminar to turbulent flow
                       Turbulence model free-stream boundary conditions
•   The initial value for the turbulent kinetic energy   can be found as follows
• The initial value for the specific kinetic energy can be found as follows
•   If you are working with external aerodynamics or virtual wind tunnels, you can use the following
    reference values for the turbulence intensity and the viscosity ratio. They work most of the
    times, but it is a good idea to have some experimental data or a better initial estimate.
                                          1                 10                  100
                                                                                                   239
     Flow past a cylinder – From laminar to turbulent flow
                                                The file 0/k
19    internalField   uniform 0.00015;
20                                                  •   We are using uniform initial conditions (line 19).
21    boundaryField
22    {                                             •   For the in patch we are using a fixedValue boundary
23        out
24        {                                             condition.
25            type           inletOutlet;
26            inletValue     uniform 0.00015;       •   For the out patch we are using an inletOutlet boundary
27            value          uniform 0.00015;
28        }                                             condition (this boundary condition avoids backflow).
29        sym1
30
31
          {
              type           symmetryPlane;
                                                    •   For the cylinder patch (which is base type wall), we
32        }                                             are using the kqRWallFunction boundary condition.
33        sym2
34        {
                                                        This is a wall function, we are going to talk about this
35            type           symmetryPlane;             when we deal with turbulence modeling. Remember,
36        }
37        in                                            we can use wall functions only if the patch is of base
38
39
          {
              type           fixedValue;
                                                        type wall.
40            value          uniform 0.00015;
41        }                                         •   The rest of the patches are constrained.
42        cylinder
43
44
          {
              type           kqRWallFunction;
                                                    •   FYI, the inlet velocity is 1 and the turbulence intensity is
45            value          uniform 0.00015;           equal to 1%.
46        }
47
48
          back
          {
                                                    •   We will study with more details how to setup the
49            type           empty;                     boundary conditions when we deal with turbulence
50        }
51        front                                         modeling in the advanced modules.
52        {
53            type           empty;
54        }
55    }
                                                                                                                   240
     Flow past a cylinder – From laminar to turbulent flow
                                                  The file 0/omega
19    internalField   uniform 0.075;
20
21    boundaryField                                     •   We are using uniform initial conditions (line 19).
22    {
23        out                                           •   For the in patch we are using a fixedValue boundary
24        {
25            type           inletOutlet;                   condition.
26            inletValue     uniform 0.075;
27
28        }
              value          uniform 0.075;             •   For the out patch we are using an inletOutlet boundary
29        sym1                                              condition (this boundary condition avoids backflow).
30        {
31
32        }
              type           symmetryPlane;
                                                        •   For the cylinder patch (which is base type wall), we
33        sym2                                              are using the omegaWallFunction boundary condition.
34        {
35            type           symmetryPlane;                 This is a wall function; we are going to talk about this
36
37
          }
          in
                                                            when we deal with turbulence modeling. Remember, we
38        {                                                 can use wall functions only if the patch is of base type
39
40
              type
              value
                             fixedValue;
                             uniform 0.075;
                                                            wall.
41        }
42        cylinder                                      •   The rest of the patches are constrained.
43        {
44
45
              type
              Cmu
                             omegaWallFunction;
                             0.09;
                                                        •   FYI, the inlet velocity is 1 and the eddy viscosity ratio is
46            kappa          0.41;                          equal to 10.
47            E              9.8;
48
49
              beta1
              value
                             0.075;
                             uniform 0.075;
                                                        •   We will study with more details how to setup the
50        }                                                 boundary conditions when we deal with turbulence
51        back
52        {                                                 modeling in the advanced modules.
53            type           empty;
54        }
55        front
56        {
57            type           empty;
58        }
59    }
                                                                                                                      241
     Flow past a cylinder – From laminar to turbulent flow
                                                 The file 0/nut
19    internalField   uniform 0;
20                                                    •   We are using uniform initial conditions (line 19).
21    boundaryField
22
23
      {
          out
                                                      •   For the in patch we are using the calculated boundary
24        {                                               condition (nut is computed from kappa and omega)
25            type           calculated;
26
27        }
              value          uniform 0;               •   For the out patch we are using the calculated
28        sym1                                            boundary condition (nut is computed from kappa and
29        {
30            type           symmetryPlane;               omega)
31        }
32        sym2                                        •   For the cylinder patch (which is base type wall), we
33        {
34            type           symmetryPlane;               are using the nutkWallFunction boundary condition.
35
36
          }
          in
                                                          This is a wall function, we are going to talk about this
37        {                                               when we deal with turbulence modeling. Remember, we
38            type           calculated;
39            value          uniform 0;
                                                          can use wall functions only if the patch is of base type
40        }                                               wall.
41        cylinder
42        {
43            type           nutkWallFunction;        •   The rest of the patches are constrained.
44            Cmu            0.09;
45            kappa          0.41;                    •   Remember, the turbulent viscosity       (nut) is equal to
46            E              9.8;
47            value          uniform 0;
48        }
49        back
50        {
51            type           empty;
52        }                                           •   We will study with more details how to setup the
53        front
54        {                                               boundary conditions when we deal with turbulence
55
56        }
              type           empty;
                                                          modeling in the advanced modules.
57    }
                                                                                                                  242
    Flow past a cylinder – From laminar to turbulent flow
                             Running the case – Setting a turbulent case
•   You will find this tutorial in the directory $PTOFC/101OF/vortex_shedding/c14
•   Feel free to use the Fluent mesh or the mesh generated with blockMesh. In this case we will use
    blockMesh.
•   To run this case, in the terminal window type:
    1.     $> foamCleanTutorials
    2.     $> blockMesh
    3.     $> renumberMesh -overwrite
           $> pimpleFoam | tee log.solver
    4.
           You will need to launch this script in a different terminal
    8.     $> paraFoam
                                                                                                      243
   Flow past a cylinder – From laminar to turbulent flow
                   Running the case – Setting a turbulent case
• In step 3 we use the utility renumberMesh to make the linear system more diagonal
  dominant, this will speed-up the linear solvers.
• In step 4 we run the simulation and save the log file. Notice that we are sending the
  job to background.
• In step 5 we use pyFoamPlotWatcher.py to plot the residuals on-the-fly. As the
  job is running in background, we can launch this utility in the same terminal tab.
• In step 6 we use the gnuplot script scripts0/plot_coeffs to plot the force
  coefficients on-the-fly. Besides monitoring the residuals, is always a good idea to
  monitor a quantity of interest. Feel free to take a look at the script and to reuse it.
• In step 7 we use the utility postProcess to compute the    value of each saved
  solution (we are going to talk about  when we deal with turbulence modeling).
                                                                                            244
   Flow past a cylinder – From laminar to turbulent flow
                                                           pimpleFoam output screen
Courant Number mean: 0.088931706 max: 0.90251464                          Courant number
deltaT = 0.040145538                         Time   step
Time = 499.97                                                                              Simulation time
PIMPLE: iteration 1                         Outer iteration 1 (nOuterCorrectors)
DILUPBiCG: Solving for Ux, Initial residual = 0.0028528538, Final residual = 9.5497298e-11, No Iterations 3
DILUPBiCG: Solving for Uy, Initial residual = 0.0068876991, Final residual = 7.000938e-10, No Iterations 3
GAMG: Solving for p, Initial residual = 0.25644342, Final residual = 0.00022585963, No Iterations 7
GAMG: Solving for p, Initial residual = 0.0073871161, Final residual = 5.2798526e-06, No Iterations 8
time step continuity errors : sum local = 3.2664019e-10, global = -1.3568363e-12, cumulative = -9.8446438e-08
GAMG: Solving for p, Initial residual = 0.16889316, Final residual = 0.00014947209, No Iterations 7
GAMG: Solving for p, Initial residual = 0.0051876466, Final residual = 3.7123156e-06, No Iterations 8
time step continuity errors : sum local = 2.2950163e-10, global = -8.0710768e-13, cumulative = -9.8447245e-08
PIMPLE: iteration 2                         Outer iteration 2 (nOuterCorrectors)
DILUPBiCG: Solving for Ux, Initial residual = 0.0013482181, Final residual = 4.1395468e-10, No Iterations 3
DILUPBiCG: Solving for Uy, Initial residual = 0.0032433196, Final residual = 3.3969121e-09, No Iterations 3
GAMG: Solving for p, Initial residual = 0.10067317, Final residual = 8.9325549e-05, No Iterations 7
GAMG: Solving for p, Initial residual = 0.0042844521, Final residual = 3.0190597e-06, No Iterations 8
time step continuity errors : sum local = 1.735023e-10, global = -2.0653335e-13, cumulative = -9.8447452e-08
GAMG: Solving for p, Initial residual = 0.0050231165, Final residual = 3.2656397e-06, No Iterations 8
DICPCG: Solving for p, Initial residual = 0.00031459519, Final residual = 9.4260163e-07, No Iterations 36            pFinal
time step continuity errors : sum local = 5.4344408e-11, global = 4.0060595e-12, cumulative = -9.8443445e-08
DILUPBiCG: Solving for omega, Initial residual = 0.00060510266, Final residual = 1.5946601e-10, No Iterations 3
DILUPBiCG: Solving for k, Initial residual = 0.0032163247, Final residual = 6.9350899e-10, No Iterations 3
bounding k, min: -3.6865398e-05 max: 0.055400108 average: 0.0015914926
ExecutionTime = 1689.51 s ClockTime = 1704 s
    Time = 500.01
    Reading field U
Writing yPlus to field yPlus Writing the field to the solution directory
                                                                                                                              246
   Flow past a cylinder – From laminar to turbulent flow
                           Using a compressible solver
• So far, we have only used incompressible solvers.
• Let us use the compressible solver rhoPimpleFoam, which is a,
    Transient solver for laminar or turbulent flow of compressible fluids for HVAC and
    similar applications. Uses the flexible PIMPLE (PISO-SIMPLE) solution for time-
    resolved and pseudo-transient simulations.
$PTOFC/101OF/vortex_shedding/c24
                                                                                         247
  Flow past a cylinder – From laminar to turbulent flow
• The following dictionaries remain unchanged
       • system/blockMeshDict
       • constant/polyMesh/boundary
• Reminder:
   • The diameter of the cylinder is 0.002 m.
   • The working fluid is air at 20° Celsius and at a sea level.
   • Isothermal flow.
   • And we are targeting for a Re = 200.
                                                                   248
   Flow past a cylinder – From laminar to turbulent flow
                             The constant directory
        • thermophysicalProperties
        • momentumTransport
                                                                               249
Flow past a cylinder – From laminar to turbulent flow
                   The thermophysicalProperties dictionary file
                                                                                                              250
Flow past a cylinder – From laminar to turbulent flow
                   The thermophysicalProperties dictionary file
                                                                                                             251
  Flow past a cylinder – From laminar to turbulent flow
                 The turbulenceProperties dictionary file
• In this dictionary file we select what model we would like to use (laminar or
  turbulent).
• This dictionary is compulsory.
• As we do not want to model turbulence, the dictionary is defined as follows,
17 simulationType laminar;
                                                                                  252
   Flow past a cylinder – From laminar to turbulent flow
                                  The 0 directory
• In this directory, we will find the dictionary files that contain the boundary and
  initial conditions for all the primitive variables.
• As we are solving the compressible laminar Navier-Stokes equations, we will
  find the following field files:
        • p                   (pressure)
        • T                   (temperature)
        • U                   (velocity field)
                                                                                  253
     Flow past a cylinder – From laminar to turbulent flow
                                               The file 0/p
                                                    •   This file contains the boundary and initial conditions
17
18
      dimensions      [1 -1 -2 0 0 0 0];
                                                        for the scalar field pressure (p). We are working
19    internalField   uniform 101325;                   with absolute pressure.
20
21
22
      boundaryField
      {
                                                    •   Contrary to incompressible flows where we defined
23        in                                            relative pressure, this is the absolute pressure.
24        {
25
26        }
              type           zeroGradient;
                                                    •   Also, pay attention to the units (line 17). The
28        out                                           pressure is defined in Pascal.
29        {
30
31
              type
              value
                             fixedValue;
                             uniform 101325;
                                                    •   We are using uniform initial conditions (line 19).
32        }
34        cylinder                                  •   For the in patch we are using a zeroGradient
35        {
36            type           zeroGradient;              boundary condition.
37        }
39        sym1                                      •   For the outlet patch we are using a fixedValue
40        {
41            type           symmetryPlane;             boundary condition.
42        }
44        sym2                                      •   For the cylinder patch we are using a zeroGradient
45        {
46            type           symmetryPlane;             boundary condition.
47        }
49        back                                      •   The rest of the patches are constrained.
50        {
51            type           empty;
52        }
54        front
55        {
56            type           empty;
57        }
58    }
                                                                                                             254
     Flow past a cylinder – From laminar to turbulent flow
                                               The file 0/T
17    dimensions      [0 0 0 -1 0 0 0];
                                                    •   This file contains the boundary and initial conditions
18                                                      for the scalar field temperature (T).
19    internalField   uniform 293.15;
20
21    boundaryField                                 •   Also, pay attention to the units (line 17). The
22    {                                                 temperature is defined in Kelvin.
23        in
24        {
25            type           fixedValue;            •   We are using uniform initial conditions (line 19).
26            value          $internalField;
27        }                                         •   For the in patch we are using a fixedValue boundary
29        out
30        {                                             condition.
31            type           inletOutlet;
32            value          $internalField;        •   For the out patch we are using a inletOutlet
33            inletValue     $internalField;
34        }                                             boundary condition (in case of backflow).
36        cylinder
37        {                                         •   For the cylinder patch we are using a zeroGradient
38            type           zeroGradient;
39        }                                             boundary condition.
41        sym1
42        {                                         •   The rest of the patches are constrained.
43            type           symmetryPlane;
44        }
46        sym2
47        {
48            type           symmetryPlane;
49        }
51        back
52        {
53            type           empty;
54        }
56        front
57        {
58            type           empty;
59        }
60    }
                                                                                                             255
     Flow past a cylinder – From laminar to turbulent flow
                                                  The file 0/U
17    dimensions      [0 1 -1 0 0 0 0];
18                                                     •   This file contains the boundary and initial conditions
19
20
      internalField   uniform (1.5 0 0);                   for the dimensional vector field U.
21    boundaryField
22    {                                                •   We are using uniform initial conditions and the
23
24
          in
          {
                                                           numerical value is (1.5 0 0) (keyword internalField in
25            type           fixedValue;                   line 19).
26            value          uniform (1.5 0 0);
27
29
          }
          out
                                                       •   For the in patch we are using a fixedValue boundary
30        {                                                condition.
31             type           inletOutlet;
32
33
                phi
                inletValue
                              phi;
                              uniform (0 0 0);
                                                       •   For the out patch we are using a inletOutlet
34              value         uniform (0 0 0);             boundary condition (in case of backflow).
35        }
37        cylinder
38        {
                                                       •   For the cylinder patch we are using a zeroGradient
39            type           fixedValue;                   boundary condition.
40            value          uniform (0 0 0);
41        }
43        sym1                                         •   The rest of the patches are constrained.
44        {
45            type           symmetryPlane;
46        }
48        sym2
49        {
50            type           symmetryPlane;
51        }
53        back
54        {
55            type           empty;
56        }
58        front
59        {
60            type           empty;
61        }
62    }
                                                                                                                256
  Flow past a cylinder – From laminar to turbulent flow
                            The system directory
                                                                                257
     Flow past a cylinder – From laminar to turbulent flow
                                             The controlDict dictionary
17    application       rhoPimpleFoam;
                                                     • This case will start from the last saved solution (startFrom). If there is
18                                                     no solution, the case will start from time 0 (startTime).
19    startFrom         startTime;
20    //startFrom         latestTime;                • It will run up to 0.3 seconds (endTime).
21
22    startTime         0;                           • The initial time step of the simulation is 0.00001 seconds (deltaT).
23
24    stopAt             endTime;
25    //stopAt     writeNow;
                                                     • It will write the solution every 0.0025 seconds (writeInterval) of
26                                                     simulation time (adjustableRunTime). The option adjustableRunTime
27    endTime           0.3;                           will adjust the time-step to save the solution at the precise intervals. This
28
29    deltaT            0.00001;                       may add some oscillations in the solution as the CFL is changing.
30
31    writeControl      adjustableRunTime;           • It will keep all the solution directories (purgeWrite).
32
33    writeInterval     0.0025;                      • It will save the solution in ascii format (writeFormat).
34
35    purgeWrite        0;                           • And as the option runTimeModifiable is on, we can modify all these
36
37    writeFormat       ascii;                         entries while we are running the simulation.
38
39    writePrecision    10;                          • In line 49 we turn on the option adjustTimeStep. This option will
40                                                     automatically adjust the time step to achieve the maximum desired
41    writeCompression off;
42                                                     courant number (line 50).
43    timeFormat        general;
44                                                   • We also set a maximum time step in line 51.
45    timePrecision     6;
46                                                   • Remember, the first time step of the simulation is done using the value
47    runTimeModifiable true;
                                                       set in line 28 and then it is automatically scaled to achieve the desired
48
49    adjustTimeStep    yes;                           maximum values (lines 66-67).
50    maxCo             1;
51    maxDeltaT         1;                           • The feature adjustTimeStep is only present in the PIMPLE family
                                                       solvers, but it can be added to any solver by modifying the source code.
                                                                                                                                258
      Flow past a cylinder – From laminar to turbulent flow
                                               The controlDict dictionary
235
236    };
                                                                                                                       259
     Flow past a cylinder – From laminar to turbulent flow
                                              The fvSchemes dictionary
                                                                                                                               260
     Flow past a cylinder – From laminar to turbulent flow
                                           The fvSolution dictionary
17    solvers                                      • To solve the pressure (p) we are using the PCG method with
18
20
      {
          p
                                                     an absolute tolerance of 1e-6 and a relative tolerance relTol
21        {                                          of 0.01.
22              solver           PCG;
23
24
                preconditioner
                tolerance
                                 DIC;
                                 1e-06;
                                                   • The entry pFinal refers to the final correction of the PISO
25              relTol           0.01;               loop. Notice that we are using macro expansion ($p) to copy
26              minIter          2;
27        }                                          the entries from the sub-dictionary p.
46        pFinal
47        {                                        • To solve U and UFinal (U.*) we are using the solver
48            $p;
49            relTol          0;                     PBiCGStab with an absolute tolerance of 1e-8 and a relative
50
51        }
              minIter         2;
                                                     tolerance relTol of 0.
53        "U.*"
54        {                                        • To solve hFinal (enthalpy) we are using the solver
55
56
              solver          PBiCGStab;
              preconditioner DILU;
                                                     PBiCGStab with an absolute tolerance of 1e-8 and a relative
57            tolerance       1e-08;                 tolerance relTol of 0.
58            relTol          0;
59
60        }
              minIter         2;
                                                   • To solve rho and rhoFinal (rho.*) we are using the diagonal
74        hFinal                                     solver (remember rho is found from the equation of state, so
75        {
76            solver          PBiCGStab;             this is a back-substitution).
77            preconditioner DILU;
78            tolerance       1e-08;               • FYI, solving for the velocity is relative inexpensive, whereas
79            relTol          0;
80            minIter         2;                     solving for the pressure is expensive.
81        }
83        "rho.*"                                  • Be careful with the enthalpy, it might cause oscillations.
84        {
85            solver         diagonal;
86        }
87    }
                                                                                                                      261
      Flow past a cylinder – From laminar to turbulent flow
                                         The fvSolution dictionary
                                                                                                                262
    Flow past a cylinder – From laminar to turbulent flow
                      Running the case – Using a compressible solver
•   You will find this tutorial in the directory $PTOFC/101OF/vortex_shedding/c24
•   Feel free to use the Fluent mesh or the mesh generated with blockMesh. In this case we will use
    blockMesh.
•   To run this case, in the terminal window type:
    1.     $> foamCleanTutorials
    2.     $> blockMesh
    3.     $> transformPoints –scale ‘(0.001 0.001 0.001)’
    4.     $> renumberMesh -overwrite
    5.     $> rhoPimpleFoam | tee log
           $> pyFoamPlotWatcher.py log
    6.
           You will need to launch this script in a different terminal
                                                                                            264
   Flow past a cylinder – From laminar to turbulent flow
                                                       rhoPimpleFoam output screen
Courant Number mean: 0.1280224248 max: 0.9885863338                          Courant number
deltaT = 3.816512052e-05                        Time   step
Time = 0.3
diagonal: Solving for rho, Initial residual = 0, Final residual = 0, No Iterations 0                         Solving for density (rho)
PIMPLE: iteration 1
DILUPBiCG: Solving for Ux, Initial residual = 0.003594731129, Final residual = 3.026673755e-11, No Iterations 5
DILUPBiCG: Solving for Uy, Initial residual = 0.01296036298, Final residual = 1.223236662e-10, No Iterations 5
DILUPBiCG: Solving for h, Initial residual = 0.01228951539, Final residual = 2.583236461e-09, No Iterations 4              h residuals
DICPCG: Solving for p, Initial residual = 0.01967621449, Final residual = 8.797612158e-07, No Iterations 77
DICPCG: Solving for p, Initial residual = 0.003109422612, Final residual = 9.943030465e-07, No Iterations 69
diagonal: Solving for rho, Initial residual = 0, Final residual = 0, No Iterations 0
time step continuity errors : sum local = 6.835363016e-11, global = 4.328592697e-12, cumulative = 2.366774797e-09
rho max/min : 1.201420286 1.201382023                                                                                         pFinal
DICPCG: Solving for p, Initial residual = 0.003160602108, Final residual = 9.794177338e-07, No Iterations 69
DICPCG: Solving for p, Initial residual = 0.0004558492254, Final residual = 9.278622052e-07, No Iterations 58
diagonal: Solving for rho, Initial residual = 0, Final residual = 0, No Iterations 0                          Solving for density (rhoFinal)
time step continuity errors : sum local = 6.38639685e-11, global = 1.446434866e-12, cumulative = 2.368221232e-09
rho max/min : 1.201420288 1.201381976                         Max/min density values
ExecutionTime = 480.88 s ClockTime = 490 s
                                                                                                                          266
    Flow past a cylinder – From laminar to turbulent flow
•   This is what you will find in each directory,
      •   c19 = blockMesh – pimpleFoam – Unsteady solver – Re = 1000000 – Spalart Allmaras turbulent model no wall functions.
      •   c20 = blockMesh – rhoPimpleFoam – Unsteady solver – Mach = 2.0 – Compressible – Laminar.
      •   c21 = blockMesh – rhoPimpleFoam –Unsteady solver – Mach = 2.0 – Unsteady solver – Compressible – K-Omega SST
          turbulent model with wall functions.
      •   c22 = blockMesh – rhoSimpleFoam – Mach = 2.0 – Steady solver – Compressible – K-Omega SST turbulent model with
          wall functions.
      •   c23 = blockMesh – rhoPimpleFoam – Mach = 2.0 – LTS Pseudo-transient solver – Compressible – K-Omega SST
          turbulent model with wall functions.
      •   c24 = blockMesh – pimpleFoam – Unsteady solver – Re = 200 – No turbulent model – Source terms (momentum)
      •   c25 = blockMesh – pimpleFoam – Unsteady solver – Re = 200 – No turbulent model – Source terms (scalar transport)
      •   c26 = blockMesh – rhoPimpleFoam – Unsteady solver – Re = 200 – Laminar, isothermal
      •   c27 = blockMesh – rhoPimpleFoam – Unsteady solver – Re = 20000 – Turbulent, compressible
      •   c28 = blockMesh – pimpleDyMFoam – Unsteady solver – Re = 200 – Laminar, moving cylinder (oscillating).
      •   c29 = blockMesh – pimpleDyMFoam/pimpleFoam – Unsteady solver – Re = 200 – Laminar, rotating cylinder using AMI
          patches.
      •   c30 = blockMesh – interFoam – Unsteady solver – Laminar, multiphase, free surface.
      •   c31 = blockMesh – pimpleFoam – Unsteady solver – Laminar with source terms and AMR.
                                                                                                                             267
Module 2
Solid modeling
                 268
                  Roadmap
                                      269
             Solid modeling – Preliminaries
• There is no wrong or right way when doing solid modeling for CFD. The
  only rule you should keep in mind is that by the end of the day you should
  get a smooth, clean, and watertight geometry.
• A watertight geometry means a close body with no holes or overlapping
  surfaces.
• Have in mind that the quality of the mesh and hence of the solution, greatly
  depends on the geometry. So always do your best when creating the
  geometry.
• During this solid modeling session we are going to show you how to get
  started with the geometry generation tools. The rest is on you.
• The best way to learn how to use these tools is by doing.
• The tool of our choice is Onshape (www.onshape.com). However, have in
  mind that all CAD and solid modeling applications have similar capabilities.
                                                                                 270
             Solid modeling – Preliminaries
• There are always many ways to accomplish a task when creating a
  geometry, this give you the freedom to work in a way that is comfortable to
  you. Hereafter we are going to show you our way.
• Before starting to create your geometry, think about a strategy to employ to
  create your design, this is what we call design intent.
        • Choose one feature over other.
        • Dimensioning strategy.
        • Order of the operations.
        • Parametrization.
        • Single or multiple parts.
        • Do I need to parametrize my design, or should I use direct
          modeling?
• We are going to work with design intent during the hands-on sessions.
                                                                                 271
                     Solid modeling – Preliminaries
                                   Geometry defeaturing
•   Many times, it is not necessary to model all the details of the geometry. In these cases you
    should consider simplifying the geometry (geometry defeaturing).
•   Geometry defeaturing can save you a lot of time when generating the mesh. So be smart,
    and use it whenever is possible.
                                                                             Do we really need to
                                                                             capture the fillet details?
     Do we need to
     model the flange?
                                                                                                           272
               Solid modeling – Preliminaries
                            Geometry defeaturing
•   Would you use all these geometry details for a CFD simulations?
                                                                      273
             Solid modeling using Onshape
• Onshape is a professional CAD/solid modeling application.
• It provides powerful parametric and direct modeling capabilities.
• It is cloud based therefore you do not need to install any software.
• Documents are shareable.
• Multiple users can work in the same document at the same time
  (simultaneous editing).
• It runs in any device with a working web browser.
• Users can implement their own features using Onshape scripting language
  (featureScript).
• Users can access and modify documents in a programmatic way using
  python or nodejs.
• It is freely available for educational use and personal use.
• To start using Onshape register at: https://cad.onshape.com/
                                                                            274
                      Solid modeling using Onshape
• Even if you have not used a CAD software before, you will find the GUI easy to use.
• You will notice that there is no save button because everything you do is
  automatically saved.
                                                                          Help
             Versioning, branching, and history menu            Toolbar
Feature list
Parts list
                                                          3D area
   Document tabs                                                                        275
                Solid modeling using Onshape
• Mouse interaction in the 3D area (it can be configured in the preference area).
Selection
Rotate
Pan
Zoom
Feature toolbar:
Sketch toolbar:
                                                                                 277
                  Solid modeling using Onshape
• Let us create this solid using the dimensions illustrated.
                                                    279
                   Solid modeling using Onshape
• In the part studio page, select the top plane and start a new sketch.
                                                                          280
                    Solid modeling using Onshape
• In the part studio page, select the top plane and start a new sketch.
                                                                          281
                     Solid modeling using Onshape
• Using the sketching features, draw the following line.
                                       When you are done sketching
                                       press the checkmark
Origin
                                                                                                            283
                 Solid modeling using Onshape
• Use the sweep feature to create a new solid.
                     Select the circle as the    Select new solid   Select the lines as the
                     face to sweep                                  sweep patch
Sweep feature
                                                                                              284
                    Solid modeling using Onshape
• At this point, you should have this solid.
    Solid name.
    Right click to rename
    or view the properties
                                                   285
                   Solid modeling using Onshape
• Let us add the new inlet to the pipe.
• Create a new sketch in the top plane or edit the initial sketch.
• Hereafter we will edit the initial sketch.
                                                                                                          286
                        Solid modeling using Onshape
• Create a plane normal to a line and passing through a point
                                                                                                  287
                        Solid modeling using Onshape
• Sketch a circle in the newly created plane.
New plane
                                                                288
                     Solid modeling using Onshape
• Using the feature extrude to create a new solid using the previous sketch.
• Extrude the circle until in intercept the solid.
                                            Add the new solid to the previous part (boolean operation)
           Feature extrusion
                                                       290
                     Solid modeling using Onshape
• If you want to know the mass properties of the solid, select it, and then click on the
  mass properties icon.
• To get the inertia, you will need to assign a material.
                                                                                           291
                     Solid modeling using Onshape
• To export the solid model, right click on the part name and select the option export.
• Choose the desired format. In this case choose STL.
                                                                                          292
               Solid modeling using Onshape
• Parametric modeling and feature-based modeling are two of the most powerful tools
  available in any CAD/solid modeling applications.
• They are crucial components in the design experience, especially when dealing with
  design intent.
• Experimenting with dimension schemes is one of the best ways to improve your
  understanding of design intent.
• To learn more about Onshape, you can visit their learning center:
                                https://learn.onshape.com/
• Finally, feel free to visit our youtube channel where you will find a few solid modeling
  videos in the context of CFD and OpenFOAM® :
          https://www.youtube.com/channel/UCNNBm3KxVS1rGeCVUU1p61g
                                                                                         293
                     Solid modeling using Onshape
• At the following links, you can find a few geometries that you can use to setup cases
  from scratch:
   • Sailing boat:
   https://cad.onshape.com/documents/ad885ed6298e6d95e372f573/w/1cfda457fe3ad410332aad9c/e/8dac4fcaf6e34a43e9676fbc
   • Mixing elbow:
   https://cad.onshape.com/documents/1cc919d8e75c2e47e8c1d50e/w/0efa002648eb2fb80ec4bec4/e/a742bf4113c626735e1d8f1a
   •    Static mixer:
   https://cad.onshape.com/documents/58f7930861743e1074559ea6/w/96672317c9167265f9d10181/e/e4b6b1baffa90ca207afe974
   • Ahmed body:
   https://cad.onshape.com/documents/e1ecbacd95be9ed0962aa410/w/f0295899197e2f3d851000fd/e/aa40f8f5d26b7117dd0a5111
   • Mixing tank:
   https://cad.onshape.com/documents/e00307c191ce168d1d8c2e05/w/fc5d69b18559ec3893a1a80a/e/ba4b5ca5b34ad7335a2915a3
   • Onera M6 wing:
   https://cad.onshape.com/documents/e176caaa70bfd4719cafe3d7/w/9d8b5771d7382000b0762e65/e/ec4669f8c28761e60e35b32f
                                                                                                                      294
          Module 3
 Meshing preliminaries – Mesh quality
assessment – Meshing in OpenFOAM®
                                        295
                            Before we begin
•   OpenFOAM® comes with the following meshing applications:
             •   blockMesh
             •   snappyHexMesh
             •   foamyHexMesh
             •   foamyQuadMesh
•   We are going to work with blockMesh and snappyHexMesh.
•   blockMesh is a multi-block mesh generator.
•   snappyHexMesh is an automatic split hex mesher, refines and snaps to surface.
•   If you are not comfortable using OpenFOAM® meshing applications, you can use an
    external mesher.
•   OpenFOAM® comes with many mesh conversion utilities. Many popular meshing
    formats are supported. To name a few: gambit, cfx, fluent, gmsh, ideas, netgen,
    plot3d, starccm, VTK.
•   In this module, we are going to address how to mesh using OpenFOAM®
    technology, how to convert meshes to OpenFOAM® format, and how to assess
    mesh quality in OpenFOAM®.
                                                                                      296
                               Before we begin
        By the end of this module, you will realize that
You will use snappyHexMesh to mesh the sphinx
                                                                                              297
                    Roadmap
1.   Meshing preliminaries
2.   What is a good mesh?
3.   Mesh quality assessment in OpenFOAM®
4.   Mesh generation using blockMesh.
5.   Mesh generation using snappyHexMesh.
6.   snappyHexMesh guided tutorials.
7.   Mesh conversion
8.   Geometry and mesh manipulation utilities
                                                298
                             Meshing preliminaries
• Mesh generation or domain discretization consist in dividing the physical
  domain into a finite number of discrete regions, called control volumes or
  cells in which the solution is sought
          www.wolfdynamics.com/wiki/moving/ani1.gif   www.wolfdynamics.com/wiki/moving/ani2.gif
                                                                                                  299
                   Meshing preliminaries
                      Mesh generation process
• Generally speaking, when generating the mesh we follow these three
  simple steps:
   • Geometry generation: we first generate the geometry that we are going
     to feed into the meshing tool.
   • Mesh generation: the mesh can be internal or external. We also define
     surface and volume refinement regions. We can also add inflation layers
     to better resolve the boundary layer. During the mesh generation
     process we also check the mesh quality.
   • Definition of boundary surfaces: in this step we define physical
     surfaces where we are going to apply the boundary conditions. If you do
     not define these individual surfaces, you will have one single surface
     and it will not be possible to apply different boundary conditions.
                                                                          300
                             Meshing preliminaries
                     Geometry generation - Input geometry
•   The geometry must be watertight.
•   Remember, the quality of the mesh and hence the quality of the solution greatly depends on the geometry. So
    always do your best when creating the geometry.
                                                                                                             301
                              Meshing preliminaries
                                         Mesh generation
•   If we are interested in external aerodynamics, we define a physical domain and we mesh the region around
    the body.
•   If we are interested in internal aerodynamics, we simply mesh the internal volume of the geometry.
•   To resolve better the flow features, we can add surface and volume refinement.
•   Remember to always check the mesh quality.
                                                                                                               302
                              Meshing preliminaries
                   Definition of boundary surfaces (patches)
•   In order to assign boundary conditions, we need to create boundary surfaces (patches) where we are going to
    apply the boundary values.
•   The boundary surfaces (patches) are created at meshing time.
•   In OpenFOAM®, you will find this information in the boundary dictionary file which is located in the directory
    constant/polyMesh. This dictionary is created automatically at meshing time.
inlet outlet
top
left right
airplane
                  bottom                                                                                         303
                                                   Meshing preliminaries
                              What cell type should I use?
• In the meshing world, there are many cell types. Just to name a few: tetrahedrons,
  pyramids, hexahedrons, prisms, polyhedral.
• Each cell type has its very own properties when it comes to approximate the gradients
  and fluxes, we are going to talk about this later on when we deal with the FVM.
• Generally speaking, hexahedral cells will give more accurate solutions under certain
  conditions.
• However, this does not mean that tetra/poly cells are not good.
• What cell type do I use? It is up to you; at the end of the day the overall quality of the
  final mesh should be acceptable, and your mesh should resolve the physics
                                                                                                                                                             304
                    Roadmap
1.   Meshing preliminaries
2.   What is a good mesh?
3.   Mesh quality assessment in OpenFOAM®
4.   Mesh generation using blockMesh.
5.   Mesh generation using snappyHexMesh.
6.   snappyHexMesh guided tutorials.
7.   Mesh conversion
8.   Geometry and mesh manipulation utilities
                                                305
                                What is a good mesh?
•     There is no written theory when it comes to mesh generation.
•     Basically, the whole process depends on user experience and good standard
      practices.
•     A standard rule of thumb is that the elements shape and distribution should be
      pleasing to the eye.
                                                                                       306
                    What is a good mesh?
•   In a more sounded way, the user can rely in mesh metrics.
•   However, no single standard benchmark or metric exists that can effectively
    assess the quality of a mesh, but the user can rely on suggested best
    practices.
•   Hereafter, we will present the most common mesh quality metrics:
        •   Orthogonality.
        •   Skewness.
        •   Aspect Ratio.
        •   Smoothness.
•   After generating the mesh, we measure these quality metrics to assess the
    mesh quality.
•   Have in mind that there are many more mesh quality metrics out there, and
    some of them are not very easy to interpret (e.g., jacobian matrix,
    determinant, flatness, equivalence, condition number, and so on).
•   It seems that it is much easier diagnosing bad meshes than good meshes.
                                                                             307
                        What is a good mesh?
          Mesh quality metrics. Mesh orthogonality
•   Mesh orthogonality is the angular deviation of the vector S (located at the face center
    f ) from the vector d connecting the two cell centers P and N. In this case is    .
•   It mainly affects the Laplacian and gradient terms at the face center f.
•   It adds numerical diffusion to the solution.
                                                                                         308
                         What is a good mesh?
             Mesh quality metrics. Mesh skewness
•   Skewness (also known as non-conjunctionality) is the deviation of the vector d that
    connects the two cells P and N, from the face center f.
•   The deviation vector is represented with         and       is the point where the vector d
    intersects the face f .
•   It affects the interpolation of the cell centered quantities at the face center f.
•   It affects the computation of the convective, diffusive, and gradient terms.
•   It adds numerical diffusion and wiggles to the solution.
                                                                                            309
                        What is a good mesh?
        Mesh quality metrics. Mesh aspect ratio AR
•   Mesh aspect ratio AR is the ratio between the longest side         and the shortest
    side    .
•   Large AR are ok if gradients in the largest direction are small.
•   High AR smear gradients.
•   Large AR can add numerical diffusion to the solution.
                                                                                          310
                        What is a good mesh?
                Mesh quality metrics. Smoothness
•   Smoothness, also known as expansion rate, growth factor or uniformity, defines the
    transition in size between contiguous cells.
•   Large transition ratios between cells add diffusion to the solution.
•   Ideally, the maximum change in mesh spacing should be less than 20%:
•     Hexes, prisms, and quadrilaterals can be stretched easily to resolve boundary layers
      without losing quality.
•     Triangular and tetrahedral meshes have inherently larger truncation error.
•     Less truncation error when faces aligned with flow direction and gradients.
Flow direction
                                                                                        312
                              What is a good mesh?
                                     Striving for quality
•         For the same cell count, hexahedral meshes will give more accurate solutions,
          especially if the grid lines are aligned with the flow.
•         But this does not mean that tetrahedral meshes are not good, by carefully choosing
          the numerical scheme you can get the same level of accuracy as in hexahedral
          meshes.
•         The problem with tetrahedral meshes is mainly related to the way gradients are
          computed.
Hexa
                              Year                                                                           313
                                                What is a good mesh?
                                                            Striving for quality
•      The mesh density should be high enough to capture all relevant flow features.
•      In areas where the solution change slowly, you can use larger elements.
•      A good mesh does not rely in the fact that the more cells we use the better the
       solution.
                                                                                                        315
                           What is a good mesh?
                                 Striving for quality
•   Use hexahedral meshes whenever is possible, specially if high accuracy in predicting forces is
    your goal (drag prediction) or for turbo machinery applications.
•   For complex flows without dominant flow direction, quad and hex meshes loose their
    advantages.
•   Keep orthogonality, skewness, and aspect ratio to a minimum.
•   Change in cell size should be smooth.
•   Always check the mesh quality. Remember, one single cell can cause divergence or give you
    inaccurate results.
•   When you strive for quality, you avoid the GIGO syndrome (garbage in, garbage out).
•   Just to end for good the mesh quality talk:
          •   A good mesh is a mesh that serves your project objectives.
          •   So, as long as your results are physically realistic, reliable and accurate; your mesh is
              good.
          •   Know your physics and generate a mesh able to resolve the physics involve, without
              over-doing.
                                                                                                     316
             What is a good mesh?
A good mesh might not lead to the ideal solution, but a bad
mesh will always lead to a bad solution.
                                       P. Baker – Pointwise
                                                              317
                    Roadmap
1.   Meshing preliminaries
2.   What is a good mesh?
3.   Mesh quality assessment in OpenFOAM®
4.   Mesh generation using blockMesh.
5.   Mesh generation using snappyHexMesh.
6.   snappyHexMesh guided tutorials.
7.   Mesh conversion
8.   Geometry and mesh manipulation utilities
                                                318
      Mesh quality assessment in OpenFOAM®
                  Mesh quality metrics in OpenFOAM®
•   In the file primitiveMeshCheck.C located in the directory
    $WM_PROJECT_DIR/src/OpenFOAM/meshes/primitiveMesh/primitiveMeshCheck/ you will find the
    quality metrics hardwired in OpenFOAM®. Their maximum (or minimum) values are defined as follows:
•   You will be able to run simulations with mesh quality errors such as high skewness, high aspect ratio, and high
    non-orthogonality. But remember, they will affect the solution accuracy, might give you strange results, and
    eventually can made the solver blow-up.
•   Have in mind that if you have bad quality meshes, you will need to adapt the numerics to deal with this kind of
    meshes. We will give you our recipe later when we deal with the numerics.
•   You should avoid as much as possible non-orthogonality values close to 90. This is an indication that you have
    zero-volume cells.
•   In overall, large aspect ratios do not represent a problem. It is just an indication that you have very fine
    meshes (which is the case when you are resolving the boundary layer).
•   The default quality metrics in OpenFOAM® seems to be a little bit conservative. In our experience, we have
    found that you can run simulations with no numerical tricks with a non-orthogonality values up to 80 and
    skewness values up to 8.                                                                                      319
      Mesh quality assessment in OpenFOAM®
            Checking the mesh quality in OpenFOAM®
•   To check the mesh quality and validity, OpenFOAM® comes with the utility checkMesh.
•   To use this utility, just type in the terminal checkMesh, and read the screen output.
•   checkMesh will look for/check for:
            •   Mesh stats and overall number of cells of each type.
            •   Check topology (boundary conditions definitions).
            •   Check geometry and mesh quality (bounding box, cell volumes, skewness, orthogonality, aspect
                ratio, and so on).
•   If for any reason checkMesh finds errors, it will give you a message and it will tell you what check failed.
•   It will also write a set with the faulty cells, faces, and/or points.
•   These sets are saved in the directory constant/polyMesh/sets/
•   Mesh topology and patch topology errors must be repaired.
•   You will be able to run with mesh quality errors such as skewness, aspect ratio, minimum face area, and non-
    orthogonality.
•   But remember, they will severely tamper the solution accuracy, might give you strange results, and eventually
    can made the solver blow-up.
•   Unfortunately, checkMesh does not repair these errors.
•   You will need to check the geometry for possible errors and generate a new mesh.
•   You can visualize the failed sets directly in paraFoam .
•   You can also convert the failed sets into VTK format by using the utility foamToVTK.
                                                                                                                   320
      Mesh quality assessment in OpenFOAM®
            Visualizing the failed sets in OpenFOAM®
                                                                        Check this box to include sets
•   You can load the failed sets directly within
    paraFoam.
•   Remember, you will need to create the sets. To
    do so, just run the checkMesh utility.
•   If there are problems in the mesh, checkMesh
    will automatically save the sets in the directory
    constant/polyMesh/sets
•   In paraFoam, simply select the option Include
    Sets and then select the sets you want to
    visualize.
•   This method only works when using the wrapper
    paraFoam.
•   If you are using paraview or a different scientific
    visualization application, you will need to convert
    the failed sets to VTK format or an alternative
    format.
•   Also, when working with large meshes we prefer
    to convert the faulty sets to VTK format.
•   To convert the faulty sets to VTK format you can      Failed sets
    use the utility foamToVTK.
                                                                                                         321
     Mesh quality assessment in OpenFOAM®
          Visualizing the failed sets in OpenFOAM®
• To convert the failed faces/cells/points to VTK format, you can proceed as follows:
    where set_type is the type of sets (faceSet, cellSet, pointSet, surfaceFields) and
    name_of_sets is the name of the set located in the directory
    constant/polyMesh/sets (highAspectRatioCells, nonOrthoFaces,
    wrongOrientedFaces, skewFaces, unusedPoints, and so on).
•   At the end, foamToVTK will create a directory named VTK, where you will find the
    failed faces/cells/points in VTK format.
•   At this point you can use paraview/paraFoam or any scientific visualization
    application to open the VTK files and visualize the failed sets.
                                                                                         322
     Mesh quality assessment in OpenFOAM®
               Checking mesh quality in OpenFOAM®
•   Sample checkMesh output,
    Mesh stats
        points:             81812
        faces:              902132
        internal faces:     871012
        cells:              443286
        faces per cell:     4                                                       Mesh stats
        boundary patches:   9
        point zones:        0
        face zones:         1
        cell zones:         1
    Checking topology...
        Boundary definition OK.                                                          Checking mesh topology
        Cell to face addressing OK.
     ***Unused points found in the mesh, number unused by faces: 16 number unused by cells: 16
      <<Writing 16 unused points to set unusedPoints
        Upper triangular ordering OK.
        Face vertices OK.
        Number of regions: 1 (OK).                                    Unused points found in the mesh
                                                                      In this case they do not harm the solution
                                                                      They can be removed using topoSet and subsetMesh
                                                                                                                         323
     Mesh quality assessment in OpenFOAM®
               Checking mesh quality in OpenFOAM®
•   Sample checkMesh output,
    Checking patch topology for multiply connected surfaces...
        Patch               Faces    Points   Surface topology
        FAIRING             1267     727      ok (non-closed singly         connected)
        FUSELAGE            3243     1774     ok (non-closed singly         connected)
        WING                15313    7706     ok (non-closed singly         connected)
        INLET               272      160      ok (non-closed singly         connected)
        OUTLET              272      160      ok (non-closed singly         connected)                        Boundary patches
        SYMM                6280     3324     ok (non-closed singly         connected)
        FARFIELD            3136     1645     ok (non-closed singly         connected)
        NOSE                76       49       ok (non-closed singly         connected)
        COCKPIT             1261     670      ok (non-closed singly         connected)
    Checking geometry...
        Overall domain bounding box (-15000 -7621.0713 -7396.4536) (30048.969 0 7446.8442)
        Mesh has 3 geometric (non-empty/wedge) directions (1 1 1)
        Mesh has 3 solution (non-empty) directions (1 1 1)
                                                                                                    Mesh bounding box
        Boundary openness (-4.2298633e-18 8.0240802e-16 4.013988e-16) OK.
        Max cell openness = 4.8098963e-16 OK.
        Max aspect ratio = 29.575835 OK.                Aspect ratio
        Minimum face area = 0.0066721253. Maximum face area = 1037224.8. Face area magnitudes OK.
        Min volume = 0.00050536842. Max volume = 3.2500889e+08. Total volume = 5.0960139e+12. Cell volumes OK.
        Mesh non-orthogonality Max: 86.939754 average: 17.939523                  High non-orthogonality
       *Number of severely non-orthogonal (> 70 degrees) faces: 3168.             But we still can run the simulation
        Non-orthogonality check OK.
      <<Writing 3168 non-orthogonal faces to set nonOrthoFaces
        Face pyramids OK.
        Max skewness = 2.5719979 OK.                Skewness
        Coupled point location match (average 0) OK.
Failed 1 mesh checks. The fact that one check failed does not mean that you can not run the simulation
    End                                                                                                                          324
     Mesh quality assessment in OpenFOAM®
             Visualization of faulty sets in paraFoam
•   You will find this case ready to use in the directory,
    $PTOFC/mesh_quality_manipulation/M1_wingbody
•   To run the case, just follow the instructions in the README.FIRST files.
               Non orthogonal faces (green spheres) and unused points (yellow spheres)   325
                    Roadmap
1.   Meshing preliminaries
2.   What is a good mesh?
3.   Mesh quality assessment in OpenFOAM®
4.   Mesh generation using blockMesh.
5.   Mesh generation using snappyHexMesh.
6.   snappyHexMesh guided tutorials.
7.   Mesh conversion
8.   Geometry and mesh manipulation utilities
                                                326
          Mesh generation using blockMesh
                              blockMesh
• “blockMesh is a multi-block mesh generator.”
• For simple geometries, the mesh generation utility blockMesh can be used.
• The mesh is generated from a dictionary file named blockMeshDict
  located in the system directory.
• This meshing tool generates high quality meshes.
• It is the tool to use for very simple geometries. As the complexity of the
  geometry increases, the effort and time required to setup the dictionary
  increases a lot.
• Usually, the background mesh used with snappyHexMesh consist of a
  single rectangular block; therefore, blockMesh can be used with no
  problem.
• It is highly recommended to create a template of the dictionary
  blockMeshDict that you can change according to the dimensions of your
  domain.
• You can also use m4 or Python scripting to automate the whole process.       327
               Mesh generation using blockMesh
                                         blockMesh
•   These are a few meshes that you can generate using blockMesh.
•   As you can see, they are not very complex.
•   However, generating the blocking topology requires some effort.
                                                                      328
           Mesh generation using blockMesh
                               blockMesh workflow
• To generate a mesh with blockMesh, you will need to define the vertices, block
  connectivity and number of cells in each direction.
• To assign boundary patches, you will need to define the faces connectivity
                                                                                   329
                        blockMesh guided tutorials
$PTOFC/101BLOCKMESH/C1
•   In the case directory, you will find the README.FIRST file. In this file, you will find the general instructions of
    how to run the case. In this file, you might also find some additional comments.
•   You will also find a few additional files (or scripts) with the extension .sh, namely, run_all.sh,
    run_mesh.sh, run_sampling.sh, run_solver.sh, and so on. These files can be used to run the case
    automatically by typing in the terminal, for example, sh run_solver.
•   We highly recommend you to open the README.FIRST file and type the commands in the terminal, in this
    way, you will get used with the command line interface and OpenFOAM® commands.
•   If you are already comfortable with OpenFOAM®, use the automatic scripts to run the cases.
                                                                                                                      330
                 blockMesh guided tutorials
                            What are we going to do?
• We will use this simple case to take a close look at a blockMeshDict dictionary.
• We will study all sections in the blockMeshDict dictionary.
• We will introduce two features useful for parameterization, namely, macro syntax and
  inline calculations.
• You can use this dictionary as a blockMeshDict template that you can change
  automatically according to the dimensions of your domain and the desired cell
  spacing.
                                                                                     331
                          blockMesh guided tutorials
                                   The blockMeshDict dictionary.
                                               •   The keyword convertToMeters (line 17), is a scaling
17   convertToMeters 1;                            factor. In this case we do not scale the dimensions.
18
19   xmin   0;
20   xmax   1;                                 •   In lines 19-24 we declare some variables using macro
21
22
     ymin
     ymax
            0;
            1;
                                                   syntax notation. With macro syntax, we first declare the
23   zmin   0;                                     variables and their values (lines 19-24), and then we can
24   zmax   1;
25
                                                   use the variables by adding the symbol $ to the variable
30   deltax 0.05;                                  name (lines 47-54).
31   deltay 0.05;
32   deltaz 0.05;
33                                             •   In lines 30-32 we use macro syntax to declare another
34   lx #calc "$xmax - $xmin";                     set of variables that will be used later.
35   ly #calc "$ymax - $ymin";
36   lz #calc "$zmax – $zmin";
37                                             •   Macro syntax is a very convenient way to parameterize
38
39
     xcells #calc "round(($lx)/($deltax))";
     ycells #calc "round(($ly)/($deltay))";
                                                   dictionaries.
40   zcells #calc "round(($lz)/($deltaz))";
41
44   vertices
45   (
46   //BLOCK 0
47       ($xmin   $ymin   $zmin)   //0
48       ($xmax   $ymin   $zmin)   //1
49       ($xmax   $ymax   $zmin)   //2
50       ($xmin   $ymax   $zmin)   //3
51       ($xmin   $ymin   $zmax)   //4
52       ($xmax   $ymin   $zmax)   //5
53       ($xmax   $ymax   $zmax)   //6
54       ($xmin   $ymax   $zmax)   //7
66   );
                                                                                                           332
                          blockMesh guided tutorials
                                   The blockMeshDict dictionary.
                                               •   In lines 34-40 we are doing inline calculations using the
17   convertToMeters 1;                            directive #calc.
18
19   xmin   0;
20   xmax   1;                                 •   Basically we are programming directly in the dictionary.
21
22
     ymin
     ymax
            0;
            1;
                                                   OpenFOAM® will compile this function as it reads it.
23   zmin   0;
24   zmax   1;                                 •   With inline calculations and codeStream you can access
25
30   deltax 0.05;
                                                   many OpenFOAM® functions from the dictionaries.
31   deltay 0.05;
32   deltaz 0.05;                              •   Inline calculations and codeStream are very convenient
33
34   lx #calc "$xmax - $xmin";
                                                   ways to parameterize dictionaries and program directly
35   ly #calc "$ymax - $ymin";                     on the dictionaries.
36   lz #calc "$zmax – $zmin";
37
38   xcells #calc "round(($lx)/($deltax))";
39   ycells #calc "round(($ly)/($deltay))";
40   zcells #calc "round(($lz)/($deltaz))";
41
44   vertices
45   (
46   //BLOCK 0
47       ($xmin   $ymin   $zmin)   //0
48       ($xmax   $ymin   $zmin)   //1
49       ($xmax   $ymax   $zmin)   //2
50       ($xmin   $ymax   $zmin)   //3
51       ($xmin   $ymin   $zmax)   //4
52       ($xmax   $ymin   $zmax)   //5
53       ($xmax   $ymax   $zmax)   //6
54       ($xmin   $ymax   $zmax)   //7
66   );
                                                                                                           333
                          blockMesh guided tutorials
                                   The blockMeshDict dictionary.
                                               •   To do inline calculations using the directive #calc, we
17   convertToMeters 1;                            proceed as follows (we will use line 35 as example):
18
19   xmin   0;
20   xmax   1;
21   ymin   0;
22   ymax   1;                                             ly #calc "$ymax - $ymin";
23   zmin   0;
24   zmax   1;
25
30   deltax 0.05;
31   deltay 0.05;                              •   We first give a name to the new variable (ly), we then tell
32   deltaz 0.05;
33
                                                   OpenFOAM® that we want to do an inline calculation
34   lx #calc "$xmax - $xmin";                     (#calc), and then we do the inline calculation ("$ymax-
35   ly #calc "$ymax - $ymin";
36   lz #calc "$zmax – $zmin";                     $ymin";). Notice that the operation must be between
37
38   xcells #calc "round(($lx)/($deltax))";
                                                   double quotation marks.
39   ycells #calc "round(($ly)/($deltay))";
40   zcells #calc "round(($lz)/($deltaz))";
41
44   vertices
45   (
46   //BLOCK 0
47       ($xmin   $ymin   $zmin)   //0
48       ($xmax   $ymin   $zmin)   //1
49       ($xmax   $ymax   $zmin)   //2
50       ($xmin   $ymax   $zmin)   //3
51       ($xmin   $ymin   $zmax)   //4
52       ($xmax   $ymin   $zmax)   //5
53       ($xmax   $ymax   $zmax)   //6
54       ($xmin   $ymax   $zmax)   //7
66   );
                                                                                                             334
                          blockMesh guided tutorials
                                   The blockMeshDict dictionary.
                                               •   In lines lines 34-36, we use inline calculations to
17   convertToMeters 1;                            compute the length in each direction.
18
19   xmin   0;
20   xmax   1;                                 •   Then we compute the number of cells to be used in each
21
22
     ymin
     ymax
            0;
            1;
                                                   direction (lines 38-40).
23   zmin   0;
24   zmax   1;                                 •   To compute the number of cells we use as cell spacing
25
30   deltax 0.05;
                                                   the values declared in lines 30-32.
31   deltay 0.05;
32   deltaz 0.05;                              •   By proceeding in this way, we can compute automatically
33
34   lx #calc "$xmax - $xmin";
                                                   the number of cells needed in each direction according to
35   ly #calc "$ymax - $ymin";                     the desired cell spacing.
36   lz #calc "$zmax – $zmin";
37
38   xcells #calc "round(($lx)/($deltax))";
39   ycells #calc "round(($ly)/($deltay))";
40   zcells #calc "round(($lz)/($deltaz))";
41
44   vertices
45   (
46   //BLOCK 0
47       ($xmin   $ymin   $zmin)   //0
48       ($xmax   $ymin   $zmin)   //1
49       ($xmax   $ymax   $zmin)   //2
50       ($xmin   $ymax   $zmin)   //3
51       ($xmin   $ymin   $zmax)   //4
52       ($xmax   $ymin   $zmax)   //5
53       ($xmax   $ymax   $zmax)   //6
54       ($xmin   $ymax   $zmax)   //7
66   );
                                                                                                         335
                          blockMesh guided tutorials
                                   The blockMeshDict dictionary.
                                               •   In the vertices section (lines 44-66), we define the vertex
17   convertToMeters 1;                            coordinates of the geometry.
18
19   xmin   0;
20   xmax   1;                                 •   In this case, there are eight vertices defining a 3D block.
21   ymin   0;
22   ymax   1;                                 •   Remember, OpenFOAM® always uses 3D meshes, even
23   zmin   0;
24   zmax   1;                                     if the simulation is 2D. For 2D meshes, you only add one
25
30   deltax 0.05;
                                                   cell in the third dimension.
31   deltay 0.05;
32   deltaz 0.05;                              •   Notice that the vertex numbering starts from 0 (as the
33
34   lx #calc "$xmax - $xmin";
                                                   counters in c++). This numbering applies for blocks as
35   ly #calc "$ymax - $ymin";                     well.
36   lz #calc "$zmax – $zmin";
37
38   xcells #calc "round(($lx)/($deltax))";
39   ycells #calc "round(($ly)/($deltay))";
40   zcells #calc "round(($lz)/($deltaz))";
41
44   vertices
45   (
46   //BLOCK 0
47       ($xmin   $ymin   $zmin)   //0
48       ($xmax   $ymin   $zmin)   //1
49       ($xmax   $ymax   $zmin)   //2
50       ($xmin   $ymax   $zmin)   //3
51       ($xmin   $ymin   $zmax)   //4
52       ($xmax   $ymin   $zmax)   //5
53       ($xmax   $ymax   $zmax)   //6
54       ($xmin   $ymax   $zmax)   //7
66   );
                                                                                                            336
                           blockMesh guided tutorials
                                       The blockMeshDict dictionary.
•   In lines 68-71, we define the block topology, hex means that it is a structured hexahedral block. In this case,
    we are generating a rectangular mesh.
•   In line 70, (0 1 2 3 4 5 6 7) are the vertices used to define the block (and yes, the order is important). Each
    hex block is defined by eight vertices, in sequential order. Where the first vertex in the list represents the
    origin of the coordinate system (vertex 0 in this case).
•   ($xcells $ycells $zcells) is the number of mesh cells in each direction (X Y Z). Notice that we are using
    macro syntax, and we compute the values using inline calculations.
•   simpleGrading (1 1 1) is the grading or mesh stretching in each direction (X Y Z), in this case the mesh is
    uniform. We will deal with mesh grading/stretching in the next case.
    68   blocks
    69   (
    70       hex (0 1 2 3 4 5 6 7) ($xcells $ycells $zcells) simpleGrading (1 1 1)
    71   );
    72
    73   edges
    74   (
    75
    76   );
                                                                                                                      337
                           blockMesh guided tutorials
                                       The blockMeshDict dictionary.
•   Let us talk about the block ordering hex (0 1 2 3 4 5 6 7), which is extremely important.
•   hex blocks are defined by eight vertices in sequential order. Where the first vertex in the list represents the
    origin of the coordinate system (vertex 0 in this case).
•   Starting from this vertex, we construct the block topology. So in this case, the first part of the block is made up
    by vertices 0 1 2 3 and the second part of the block is made up by vertices 4 5 6 7 (notice that we start from
    vertex 4 which is the projection in the Z-direction of vertex 0).
•   In this case, the vertices are ordered in such a way that if we look at the screen/paper (-z direction), the
    vertices rotate counter-clockwise.
•   If you add a second block, you must identify the first vertex and starting from it, you should construct the block
    topology. In this case, you will need to merges faces, you will find more information about merging face in the
    supplement lectures.
    68   blocks
    69   (
    70       hex (0 1 2 3 4 5 6 7) ($xcells $ycells $zcells) simpleGrading (1 1 1)
    71   );
    72
    73   edges
    74   (
    75
    76   );
                                                                                                                      338
                           blockMesh guided tutorials
                                       The blockMeshDict dictionary.
•   Edges, are constructed from the vertices definition.
•   Each edge joining two vertices is assumed to be straight by default.
•   The user can specify any edge to be curved by entries in the section edges.
•   Possible options are Bspline, arc, line, polyline, project, projectCurve, spline.
•   For example, to define an arc we first define the vertices to be connected to form an edge and then we give an
    interpolation point.
•   To define a polyline we first define the vertices to be connected to form an edge and then we give a list of the
    coordinates of the interpolation points.
•   In this case and as we do not specify anything, all edges are assumed to be straight lines.
    68   blocks
    69   (
    70       hex (0 1 2 3 4 5 6 7) ($xcells $ycells $zcells) simpleGrading (1 1 1)
    71   );
    72
    73   edges
    74   (
    75
    76   );
                                                                                                                  339
                           blockMesh guided tutorials
                                The blockMeshDict dictionary.
                                            •   In the section boundary, we define all the patches where
78    boundary                                  we want to apply boundary conditions.
79    (
80        top
81        {                                 •   This step is of paramount importance, because if we do
82
83
              type wall;
              faces
                                                not define the surface patches, we will not be able to
84            (                                 apply the boundary conditions to individual surface
85                (3 7 6   2)
86            );
                                                patches.
87        }
88        left
89        {
90            type wall;
91            faces
92            (
93                (0 4 7   3)
94            );
95        }
96        right
97        {
98            type wall;
99            faces
100           (
101               (2 6 5   1)
102           );
103       }
104       bottom
105       {
106           type wall;
107           faces
108           (
109               (0 1 5   4)
110           );
111       }
                                                                                                     340
                           blockMesh guided tutorials
                                The blockMeshDict dictionary.
                                            •   In lines 80-87 we define a boundary patch.
78    boundary
79    (                                     •   In line 80 we define the patch name top (the name is
80        top
81        {                                     given by the user).
82            type wall;
83            faces                         •   In line 82 we give a base type to the surface patch. In
84            (
85                (3 7 6   2)                   this case wall (do not worry we are going to talk about
86
87        }
              );                                this later).
88        left
89        {                                 •   In line 85 we give the connectivity list of the vertices that
90
91
              type wall;
              faces
                                                made up the surface patch or face, that is, (3 7 6 2).
92            (
93                (0 4 7   3)               •   Have in mind that the vertices need to be neighbors and
94
95        }
              );
                                                it does not matter if the ordering is clockwise or
96        right                                 counterclockwise.
97        {
98            type wall;
99            faces
100           (
101               (2 6 5   1)
102           );
103       }
104       bottom
105       {
106           type wall;
107           faces
108           (
109               (0 1 5   4)
110           );
111       }
                                                                                                           341
                           blockMesh guided tutorials
                                The blockMeshDict dictionary.
                                            •   Have in mind that the vertices need to be neighbors and
78    boundary                                  it does not matter if the ordering is clockwise or
79    (
80        top                                   counterclockwise.
81        {
82
83
              type wall;
              faces
                                            •   Remember, faces are defined by a list of 4 vertex
84            (                                 numbers, e.g., (3 7 6 2).
85                (3 7 6   2)
86
87        }
              );                            •   In lines 88-95 we define the patch left.
88        left
89        {                                 •   In lines 96-103 we define the patch right.
90            type wall;
91            faces                         •   In lines 104-11 we define the patch bottom.
92            (
93                (0 4 7   3)
94            );
95        }
96        right
97        {
98            type wall;
99            faces
100           (
101               (2 6 5   1)
102           );
103       }
104       bottom
105       {
106           type wall;
107           faces
108           (
109               (0 1 5   4)
110           );
111       }
                                                                                                     342
                         blockMesh guided tutorials
                               The blockMeshDict dictionary.
                                           •   In lines 112-119 we define the patch front.
112        front
113        {                               •   In lines 120-127 we define the patch back.
114            type wall;
115
116
               faces
               (
                                           •   You can also group many faces into one patch, for
117                (4 5 6 7)                   example, instead of creating the patches front and back,
118            );
119        }                                   you can group them into a single patch named
120
121
           back
           {
                                               backAndFront, as follows,
122            type wall;
123            faces
124            (
125                (0 3 2 1)                   backAndFront
126            );                              {
127        }
128   );                                           type wall;
129                                                faces
130   mergePatchPairs
131   (                                            (
132                                                     (4 5 6 7)
133   );
                                                        (0 3 2 1)
                                                   );
                                               }
                                                                                                    343
                         blockMesh guided tutorials
                               The blockMeshDict dictionary.
                                           •   We can merge blocks in the section mergePatchPairs
112        front                               (lines 130-133).
113        {
114            type wall;
115            faces                       •   The block patches to be merged must be first defined in
116            (                               the boundary list, blockMesh then connect the two
117                (4 5 6 7)
118            );                              blocks.
119        }
120
121
           back
           {
                                           •   In this case, as we have one single block there is no
122            type wall;                      need to merge patches.
123            faces
124            (
125                (0 3 2 1)
126            );
127        }
128   );
129
130   mergePatchPairs
131   (
132
133   );
                                                                                                       344
                        blockMesh guided tutorials
                                 The blockMeshDict dictionary.
                                                                 345
                             blockMesh guided tutorials
                         The constant/polyMesh/boundary dictionary
18
19
     6
     (
                                        •   First of all, this file is automatically generated after you
20       top                                create the mesh or you convert it from a third-party format.
21       {
22               type        wall;
23               inGroups    1(wall);   •   In this file, the geometrical information related to the base
24               nFaces      400;
25               startFace   22800;         type patch of each boundary of the domain is specified.
26       }
27       left
28       {                              •   The base type boundary condition is the actual surface
29               type        wall;
30               inGroups    1(wall);       patch where we are going to apply a primitive type
31
32
                 nFaces
                 startFace
                             400;
                             23200;
                                            boundary condition (or numerical boundary condition).
33       }
34
35
         right
         {
                                        •   The primitive type boundary condition assign a field value
36               type        empty;         to the surface patch.
37               inGroups    1(wall);
38               nFaces      400;
39               startFace   23600;     •   You define the numerical type patch (or the value of the
40       }
41       bottom                             boundary condition), in the directory 0 or time directories.
42       {
43             type          wall;
44             inGroups      1(wall);   •   The name and base type of the patches was defined in the
45
46
               nFaces
               startFace
                             400;
                             24000;
                                            dictionary blockMeshDict in the section boundary.
47       }
48       front
49       {                              •   You can change the name if you do not like it. Do not use
50
51
               type
               inGroups
                             wall;
                             1(wall);
                                            strange symbols or white spaces.
52             nFaces        400;
53
54       }
               startFace     24400;     •   You can also change the base type. For instance, you can
55       back                               change the type of the patch top from wall to patch.
56       {
57             type          empty;
58             inGroups      1(wall);
59             nFaces        400;
60             startFace     24800;
61       }
62   )                                                                                                      346
                             blockMesh guided tutorials
                         The constant/polyMesh/boundary dictionary
18
19
     6
     (
                                        •   If you do not define the boundary patches in the dictionary
20       top                                blockMeshDict, they are grouped automatically in a default
21       {
22               type        wall;          group named defaultFaces of type empty.
23               inGroups    1(wall);
24
25
                 nFaces
                 startFace
                             400;
                             22800;
                                        •   For instance, if you do not assign a base type to the patch
26       }                                  front, it will be grouped as follows:
27       left
28       {
29               type        wall;
30               inGroups    1(wall);
31               nFaces      400;
                                            defaultFaces
32               startFace   23200;         {
33       }                                        type               empty;
34       right                                    inGroups           1(empty);
35       {
36               type        empty;
                                                  nFaces             400;
37               inGroups    1(wall);             startFace          24800;
38               nFaces      400;           }
39               startFace   23600;
40       }
41       bottom
42       {
43             type          wall;      •   Remember, you can manually change the name and type.
44             inGroups      1(wall);
45             nFaces        400;
46             startFace     24000;
47       }
48       front
49       {
50             type          wall;
51             inGroups      1(wall);
52             nFaces        400;
53             startFace     24400;
54       }
55       back
56       {
57             type          empty;
58             inGroups      1(wall);
59             nFaces        400;
60             startFace     24800;
61       }
62   )                                                                                                    347
                             blockMesh guided tutorials
                         The constant/polyMesh/boundary dictionary
18
19
     6
     (
                                              Number of surface patches
20       top
21       {
22               type        wall;            In the list bellow there must be 6 patches
23               inGroups    1(wall);
24               nFaces      400;             definition.
25               startFace   22800;
26       }
27       left
28       {
29               type        wall;
30               inGroups    1(wall);                                top
31               nFaces      400;
32               startFace   23200;
33       }
34       right
35       {
36               type        empty;
37               inGroups    1(wall);            back
38               nFaces      400;
39               startFace   23600;
40       }
41       bottom
42       {
43             type          wall;
44             inGroups      1(wall);
45             nFaces        400;             left                                            right
46             startFace     24000;
47       }
48       front
49       {
50             type          wall;
51             inGroups      1(wall);
52             nFaces        400;                                                          front
53             startFace     24400;
54       }
55       back
56       {
57             type          empty;
58             inGroups      1(wall);
59             nFaces        400;                                  bottom
60             startFace     24800;
61       }
62   )                                                                                                348
                             blockMesh guided tutorials
                         The constant/polyMesh/boundary dictionary
18   6
19   (
20       top
21       {
22               type        wall;            Name and type of the surface patches
23               inGroups    1(wall);
24               nFaces      400;
25               startFace   22800;
26       }                                    •   The name and base type of the patch is given
27       left
28       {                                        by the user.
29               type        wall;
30
31
                 inGroups
                 nFaces
                             1(wall);
                             400;
                                              •   In this case the name and base type was
32               startFace   23200;               assigned in the dictionary blockMeshDict.
33       }
34       right
35       {                                    •   You can change the name if you do not like it.
36
37
                 type
                 inGroups
                             wall;
                             1(wall);
                                                  Do not use strange symbols or white spaces.
38               nFaces      400;
39               startFace   23600;           •   You can also change the base type. For
40       }
41       bottom                                   instance, you can change the type of the
42
43
         {
               type          wall;
                                                  patch top from wall to patch.
44             inGroups      1(wall);
45             nFaces        400;
46             startFace     24000;
47       }
48       front
49       {
50             type          wall;
51             inGroups      1(wall);
52             nFaces        400;
53             startFace     24400;
54       }
55       back
56       {
57             type          wall;
58             inGroups      1(wall);
59             nFaces        400;
60             startFace     24800;
61       }
62   )                                                                                             349
                             blockMesh guided tutorials
                         The constant/polyMesh/boundary dictionary
18   6
19   (
20       top
21       {
22               type        wall;            inGroups keyword
23               inGroups    1(wall);
24               nFaces      400;
25               startFace   22800;
26       }                                    •   This is optional.
27       left
28
29
         {
                 type        wall;            •   You can erase this information safely.
30               inGroups    1(wall);
31               nFaces      400;             •   It is used to group patches during visualization
32               startFace   23200;
33       }                                        in ParaView/paraFoam. If you open this mesh
34       right
35       {                                        in paraFoam you will see that there are two
36
37
                 type
                 inGroups
                             wall;
                             1(wall);
                                                  groups, namely: wall and empty.
38               nFaces      400;
39               startFace   23600;           •   As usual, you can change the name.
40       }
41
42
         bottom
         {                                    •   If you want to put a surface patch in two
43
44
               type
               inGroups
                             wall;
                             1(wall);
                                                  groups, you can proceed as follows:
45             nFaces        400;
46             startFace     24000;                       2(wall wall1)
47       }
48
49
         front
         {
                                                  In this case the surface patch belongs to the
50
51
               type
               inGroups
                             wall;
                             1(wall);
                                                  group wall (which can have another patch)
52             nFaces        400;                 and the group wall1
53             startFace     24400;
54       }
55       back
56       {
57             type          wall;
58             inGroups      1(wall);
59             nFaces        400;
60             startFace     24800;
61       }
62   )                                                                                               350
                             blockMesh guided tutorials
                         The constant/polyMesh/boundary dictionary
18   6
19   (
20       top
21       {
22               type        wall;            nFaces and startFace keywords
23               inGroups    1(wall);
24               nFaces      400;
25               startFace   22800;
26       }                                    •   Unless you know what are you doing, you do
27       left
28       {                                        not need to change this information.
29               type        wall;
30
31
                 inGroups
                 nFaces
                             1(wall);
                             400;
                                              •   Basically, this is telling you the starting face
32               startFace   23200;               and ending face of the patch.
33       }
34       right
35       {                                    •   This information is created automatically when
36
37
                 type
                 inGroups
                             wall;
                             1(wall);
                                                  generating the mesh or converting the mesh.
38               nFaces      400;
39               startFace   23600;
40       }
41       bottom
42       {
43             type          wall;
44             inGroups      1(wall);
45             nFaces        400;
46             startFace     24000;
47       }
48       front
49       {
50             type          wall;
51             inGroups      1(wall);
52             nFaces        400;
53             startFace     24400;
54       }
55       back
56       {
57             type          wall;
58             inGroups      1(wall);
59             nFaces        400;
60             startFace     24800;
61       }
62   )                                                                                               351
                 blockMesh guided tutorials
                                Running the case
    1.   $> foamCleanTutorials
    2.   $> blockMesh
    3.   $> checkMesh
    4.   $> paraFoam
• You can run the rest of the cases following the same steps.
                                                                         352
                             blockMesh guided tutorials
                                       Final remarks on blockMesh
•   For the moment, we will limit the use of blockMesh to single-block mesh topologies, which are
    used to run some simple cases and are the starting point for snappyHexMesh.
•   But have in mind that you can do more elaborated meshes, however, it requires careful setup of
    the input dictionary.
•   Have in mind that it can be really tricky to generate multi-block meshes with curve edges.
•   With the training material, you will find a set of supplement slides where we explain how to
    create multi-block meshes, add stretching, and how to define curve edges.
        Single-block mesh with multi-stretching   Multi-block mesh with curved edges and   Multi-block mesh with face merging
                                                              multi-stretching
                                                                                                                                353
                    Roadmap
1.   Meshing preliminaries
2.   What is a good mesh?
3.   Mesh quality assessment in OpenFOAM®
4.   Mesh generation using blockMesh.
5.   Mesh generation using snappyHexMesh.
6.   snappyHexMesh guided tutorials.
7.   Mesh conversion
8.   Geometry and mesh manipulation utilities
                                                354
               Mesh generation using snappyHexMesh
                          snappyHexMesh
• “Automatic split hex mesher. Refines and snaps to surface.”
• For complex geometries, the mesh generation utility snappyHexMesh can be used.
• The snappyHexMesh utility generates 3D meshes containing hexahedra and split-
  hexahedra from a triangulated surface geometry in Stereolithography (STL) format.
• The mesh is generated from a dictionary file named snappyHexMeshDict located in
  the system directory and a triangulated surface geometry file located in the directory
  constant/triSurface.
                                                                                      355
               Mesh generation using snappyHexMesh
                             snappyHexMesh workflow
•   To generate a mesh with snappyHexMesh we proceed as follows:
             • Generation of a background or base mesh.
             • Geometry definition.
             • Generation of a castellated mesh or cartesian mesh.
             • Generation of a snapped mesh or body fitted mesh.
             • Addition of layers close to the surfaces or boundary layer meshing.
             • Check/enforce mesh quality.
snappyHexMesh
OpenFOAM mesh
                                                                                      356
             Mesh generation using snappyHexMesh
             snappyHexMesh workflow – Background mesh
• The background or base mesh can be generated using blockMesh or an
  external mesher.
• The following criteria must be observed when creating the background
  mesh:
           • The mesh must consist purely of hexes.
           • The cell aspect ratio should be approximately 1, at least near the
             STL surface.
           • There must be at least one intersection of a cell edge with the
             STL surface.
                          blockMesh or external mesher
snappyHexMesh
OpenFOAM mesh
                                                                                       357
              Mesh generation using snappyHexMesh
              snappyHexMesh workflow – Geometry (STL file)
• The STL geometry can be obtained from any geometry modeling tool.
• The STL file can be made up of a single surface describing the geometry, or
  multiple surfaces that describe the geometry.
• In the case of a STL file with multiple surfaces, we can use local refinement
  in each individual surface. This gives us more control when generating the
  mesh.
• The STL geometry is always located in the directory
  constant/triSurface
snappyHexMesh
OpenFOAM mesh
                                                                                         358
              Mesh generation using snappyHexMesh
                         snappyHexMesh workflow
• The meshing utility snappyHexMesh reads the dictionary
  snappyHexMeshDict located in the directory system.
• The castellation, snapping, and boundary layer meshing steps are controlled
  by the dictionary snappyHexMeshDict.
• The final mesh is always located in the directory
  constant/polyMesh
snappyHexMesh
OpenFOAM mesh
                                                                                        359
                          Mesh generation using snappyHexMesh
                                 snappyHexMesh workflow
• All the volume and surface refinement is done in reference to the
  background or base mesh.
and so on …
Base cell – RL 0 RL 1 RL 2
* RL = refinement level
                                                   Note:
                                                   • In 2D each quad is subdivided in 4
                                                      quads.
                                                   • In 3D each hex is subdivided in 8
                                                      hexes.
                                                                                          360
                    Mesh generation using snappyHexMesh
                                     snappyHexMesh workflow
•   The process of generating a mesh using snappyHexMesh will be described using this figure.
•   The objective is to mesh a rectangular shaped region (shaded grey in the figure) surrounding an object
    described by a STL surface (shaded green in the figure).
•   This is an external mesh (e.g. for external aerodynamics).
•   You can also generate an internal mesh (e.g. flow inside a pipe).                                        361
                      Mesh generation using snappyHexMesh
                                         snappyHexMesh workflow
                                                                                                                                   363
                        Mesh generation using snappyHexMesh
                                             snappyHexMesh workflow
                                                                                                                                              364
                       Mesh generation using snappyHexMesh
                                           snappyHexMesh workflow
                                                                                                                                         365
                       Mesh generation using snappyHexMesh
                                           snappyHexMesh workflow
                                                                                                                                         366
                       Mesh generation using snappyHexMesh
                                           snappyHexMesh workflow
                                                   369
        Mesh generation using snappyHexMesh
$PTOFC/101SHM/M101_WD
                                                      370
                         Mesh generation using snappyHexMesh
                        Let us explore the snappyHexMeshDict dictionary.
castellatedMesh true;        //or false                      •    Have in mind that there are more than 70
snap true;                   //or false
addLayers true;              //or false                           parameters to control in
                                                                  snappyHexMeshDict dictionary.
       geometry
       {
             ...                                             •    Adding the fact that there is no native GUI, it
             ...                                                  can be quite tricky to control the mesh
       }
                                                                  generation process.
       castellatedMeshControls
       {
               ...                                           •    Nevertheless, snappyHexMesh generates
               ...
       }                                                          very good hexa dominant meshes.
       snapControls
       {                                                     •    Hereafter, we will only comment on the most
             ...
             ...
                                                                  important parameters.
       }
               regions                                              Use this option if you have a STL with multiple patches defined
               {
                         wolflocal                                  This is the name of the region or surface patch in the STL
                         {
                                name wolf_wall;                     User-defined patch name. This is the final name of the patch
                         }
               }
      }
                                                                            •   In this section we read in the STL geometry. Remember, the input
      box                              Name of geometrical entity
                                                                                geometry is always located in the directory constant/triSurface
      {
               type searchableBox;                                          •   We can also define geometrical entities that can be used to refine the
               min (-100.0 -120.0 -50.0 );                                      mesh, create regions, or generate baffles.
               max (100.0 120.0 150.0 );
      }                                                                     •   You can add multiple STL files.
      sphere                           Name of geometrical entity           •   If you do not give a name to the surface, it will take the name of the
      {                                                                         STL file.
               type searchableSphere;                  Note 1
               centre (120.0 -100.0 50.0 );                                 •   The geometrical entities are created inside snappyHexMesh.
               radius 40.0;
      }                                                                     Note 1:
                                                                            If you want to know what geometrical entities are available, just
}                                                                           misspelled something in the type keyword.
                                                                                                                                                         373
                        Mesh generation using snappyHexMesh
                     Let us explore the snappyHexMeshDict dictionary.
                                                                            Castellated mesh controls section
castellatedMeshControls
{
        //Refinement parameters
        maxLocalCells 100000;
        maxGlobalCells 2000000;                       Note 1
        nCellsBetweenLevels 3;
                ...
                ...
       // Refinement parameters
       maxLocalCells 100000;
       maxGlobalCells 2000000;
       minRefinementCells 0;
       maxLoadUnbalance 0.10;
       nCellsBetweenLevels 3;                          Note 1
planarAngle 30;
allowFreeStandingZoneFaces true;
       ...
       ...
       ...
                     regions                            Note 2
                     {
                               wolflocal                              Note 3
                                                                                         Note 1:
                               {
                                                                                         The surface wolf was defined in the geometry section.
                                      level (2 4);                    Local refinement
                                                                                         Note 2:
                                       patchInfo
                                                                                         The region wolflocal was defined in the geometry section.
                                       {
                                              type wall;              Note 4
                                                                                         Note 3:
                                       }
                                                                                         Named region in the STL file. This refinement is local.
                               }
                                                                                         To use the surface refinement in the regions, the local
                     }
                                                                                         regions must exist in STL file. We created a pointer to this
              }
                                                                                         region in the geometry section.
       ...
       ...
                                                                                         Note 4:
       }                                                                                                                                           376
                                                                                         You can only define patches of type wall or patch.
                       Mesh generation using snappyHexMesh
                    Let us explore the snappyHexMeshDict dictionary.
                                                                                      Castellated mesh controls section
castellatedMeshControls
{
       ...
       ...
       ...
              //This surface or geometrical entity
              //was defined in geometry section
              sphere                                 Note 1
              {
                      level (1 1);
                                                              Name of faceZone
                     faceZone face_inner;
                     cellZone cell_inner;                     Name of cellZone
       ...
       ...
       ...
       //Region-wise refinement
       refinementRegions                      Dictionary block
       {
              box                            Note 1
              {
                      mode inside;
                      levels (( 1 1 ));
              }
                                                                                                                                          378
                        Mesh generation using snappyHexMesh
                     Let us explore the snappyHexMeshDict dictionary.
                                                                            Castellated mesh controls section
castellatedMeshControls
{
       ...
       ...
       ...
       //Region-wise refinement
       refinementRegions                      Dictionary block
       {
              box
              {
                      mode inside;
                      levels (( 1 1 ));
              }
       }
                                                                 This point defines where do you want the mesh.
                                                                 Can be internal mesh or external mesh.
       //Mesh selection
       locationInMesh (-100.0 0.0 50.0 );                        •   If the point is inside the STL it is an internal mesh.
                                                                 •   If the point is inside the background mesh and outside the
}                                                                    STL it is an external mesh.
tolerance 2.0;
// Feature snapping
       layers                                 Note 1
       {
                wolf_wall                     Note 2
                {
                      nSurfaceLayers 3;
                      //Local parameters
                      //expansionRatio        1.3;
                      //finalLayerThickness   0.3;
                      //minThickness          0.1;
                }
       }
       // Advanced settings
       nGrow 0;
       featureAngle 130;                      Note 3   Note 1:
       maxFaceThicknessRatio 0.5;                      In this section we select the patches where we want to add the
       nSmoothSurfaceNormals 1;                        layers. We can add multiple patches (if they exist).
       nSmoothThickness 10;
       minMedianAxisAngle 90;                          Note 2:
       maxThicknessToMedialRatio 0.3;                  This patch was created in the geometry section.
       nSmoothNormals 3;
       slipFeatureAngle 30;                            Note 3:
       nRelaxIter 5;                                   Specification of feature angle above which layers are collapsed
       nBufferCellsNoExtrude 0;                        automatically.
       nLayerIter 50;
       nRelaxedIter 20;                                •   In this step, we are generating the boundary layer mesh.
}                                                                                                                        381
                       Mesh generation using snappyHexMesh
                      Let us explore the snappyHexMeshDict dictionary.
                                                               Mesh quality controls section
meshQualityControls
{
     maxNonOrtho 75;                   Note 1
maxBoundarySkewness 20;
maxInternalSkewness 4; Note 2
maxConcave 80;
minVol 1E-13;
      //minTetQuality 1e-15;
      minTetQuality -1e+30;
minArea -1;
minTwist 0.02;
      minDeterminant 0.001;
                                                Note 1:
                                                Maximum non-orthogonality angle.
      minFaceWeight 0.05;
                                                Note 2:
      minVolRatio 0.01;
                                                Maximum skewness angle.
      minTriangleTwist -1;
                                                •   During the mesh generation process, the mesh quality is continuously
                                                    monitored.
      minFlatness 0.5;                          •   The mesher snappyHexMesh will try to generate a mesh using the
                                                    mesh quality parameters defined by the user.
      nSmoothScale 4;
                                                •   If a mesh motion or topology change introduces a poor quality cell or
                                                    face the motion or topology change is undone to revert the mesh back
      errorReduction 0.75;
                                                    to a previously valid error free state.
}
                                                                                                                            382
                          Mesh generation using snappyHexMesh
                        Let us explore the snappyHexMeshDict dictionary.
                                                                Mesh debug and write controls sections
debugFlags
(
      // write intermediate meshes
      mesh
writeFlags
(
        // write volScalarField with cellLevel for          •    At the end of the dictionary you will find the sections: debugFlags
        // postprocessing                                        and writeFlags
        scalarLevels
                                                            •    By default they are commented. If you uncomment them you will
        // write cellSets, faceSets of faces in layer            enable debug information.
        layerSets
                                                            •    debugFlags and writeFlags will produce a lot of outputs that you
        // write volScalarField for layer coverage               can use to post process and troubleshoot the different steps of
        layerFields                                              the meshing process.
);
                                                                                                                                       383
                   Mesh generation using snappyHexMesh
                Let us generate the mesh of the wolf dynamics logo.
•   This tutorial is located in the directory:
           •   $PTOFC/101SHM/M101_WD
•   In this case we are going to generate a body fitted mesh with boundary layer. This is an
    external mesh.
•   Before generating the mesh take a look at the dictionaries and files that will be used.
•   These are the dictionaries and files that will be used.
           •   system/snappyHexMeshDict
           •   system/surfaceFeaturesDict
           •   system/meshQualityDict
           •   system/blockMeshDict
           •   constant/triSurface/wolfExtruded.stl
           •   constant/triSurface/wolfExtruded.eMesh
•   The file wolfExtruded.eMesh is generated after using the utility surfaceFeatures, which
    reads the dictionary surfaceFeaturesDict.
                                                                                               384
             Mesh generation using snappyHexMesh
           Let us generate the mesh of the wolf dynamics logo.
  1.   $> foamCleanTutorials
  2.   $> blockMesh
  3.   $> surfaceFeatures
  4.   $> snappyHexMesh
  5.   $> checkMesh –latestTime
• In the case directory you will find the time folders 1, 2, and 3, which contain
  the castellated mesh, snapped mesh and boundary layer mesh respectively.
  In this case, snappyHexMesh automatically saved the intermediate steps.
• Before running the simulation, remember to transfer the solution from the
  latest mesh to the directory constant/polyMesh, in the terminal type:
                                                                               386
              Mesh generation using snappyHexMesh
            Let us generate the mesh of the wolf dynamics logo.
• If you want to avoid the additional steps of transferring the final mesh to the
  directory constant/polyMesh by not saving the intermediate steps, you
  can proceed as follows:
18   9                                 Name
19   (                                                  Name and type of the surface patches
20       minX
21       {                                              • The name and base type of the patch is given by the user.
22              type        wall;        Type
23              inGroups    1(wall);
24              nFaces      400;                        •   In this case the name and base type was assigned in the
25
26       }
                startFace   466399;
                                                            dictionaries blockMeshDict and snappyHexMeshDict.
27       maxX
28       {
                                              nFaces    •   You can change the name if you do not like it. Do not use
29              type        wall;
30              inGroups    1(wall);          startFace     strange symbols or white spaces.
31              nFaces      400;
32
33       }
                startFace   466799;
                                                        •   You can also change the base type. For instance, you can
34       minY                                               change the type of the patch maxY from wall to patch.
35       {
36              type        empty;
37              inGroups    1(wall);
38              nFaces      400;
39              startFace   467199;                     nFaces and startFace keywords
40       }
41       maxY                                           • Unless you know what are you doing, you do not
42       {
43              type        wall;                          need to change this information.
44              inGroups    1(wall);
45
46
                nFaces
                startFace
                            400;
                            467599;
                                                        •   Basically, this is telling you the starting face and ending face
47       }                                                  of the patch.
48       minZ
49       {
50              type        wall;                       •   This information is created automatically when generating
51
52
                inGroups
                nFaces
                            1(wall);
                            400;
                                                            the mesh or converting the mesh.
53              startFace   467999;
54       }
                                                                                                                          390
                        Mesh generation using snappyHexMesh
                            The constant/polyMesh/boundary file
55       maxZ
56       {                                         Name and type of the surface patches
57              type        wall;
58              inGroups    1(wall);               • The name and base type of the patch is given by the user.
59              nFaces      400;
60              startFace   466399;
61       }                             Name        •   In this case the name and base type was assigned in the
62
63
         wolf_wall
         {
                                                       dictionaries blockMeshDict and snappyHexMeshDict.
64             type         wall;      Type
65             inGroups     1(wall);               •   You can change the name if you do not like it. Do not use
66             nFaces       400;
67             startFace    466799;                    strange symbols or white spaces.
68       }
69
70
         sphere
         {                               nFaces    •   You can also change the base type. For instance, you can
71             type         empty;       startFace     change the type of the patch maxY from wall to patch.
72             inGroups     1(wall);
73             nFaces       400;
74             startFace    467199;
75       }
76       sphere_slave                              nFaces and startFace keywords
77       {
78             type         wall;                  • Unless you know what are you doing, you do not
79             inGroups     1(wall);
80             nFaces       400;                      need to change this information.
81             startFace    467599;
82
83   )
         }
                                                   •   Basically, this is telling you the starting face and ending face
                                                       of the patch.
                                                   •   This information is created automatically when generating
                                                       the mesh or converting the mesh.
                                                                                                                     391
              Mesh generation using snappyHexMesh
• $> foamCleanTutorials
• $> foamCleanPolyMesh
• If you are planning to start the meshing from a previous saved state, you do
  not need to clean the case directory.
                                                                             392
                    Roadmap
1.   Meshing preliminaries
2.   What is a good mesh?
3.   Mesh quality assessment in OpenFOAM®
4.   Mesh generation using blockMesh.
5.   Mesh generation using snappyHexMesh.
6.   snappyHexMesh guided tutorials.
7.   Mesh conversion
8.   Geometry and mesh manipulation utilities
                                                393
            snappyHexMesh guided tutorials
•   Our first case will be a mesh around a cylinder.
•   This is a simple geometry, but we will use it to study all the meshing steps
    and introduce a few advanced features.
•   This case is located in the directory $PTOFC/101SHM/M1cyl
                                                                                   394
                 snappyHexMesh guided tutorials
$PTOFC/101SHM/M1_cyl/C1
•   In the case directory, you will find the README.FIRST file. In this file, you will find the general instructions of
    how to run the case. In this file, you might also find some additional comments.
•   You will also find a few additional files (or scripts) with the extension .sh, namely, run_all.sh,
    run_mesh.sh, run_sampling.sh, run_solver.sh, and so on. These files can be used to run the case
    automatically by typing in the terminal, for example, sh run_solver.
•   We highly recommend you to open the README.FIRST file and type the commands in the terminal, in this
    way, you will get used with the command line interface and OpenFOAM® commands.
•   If you are already comfortable with OpenFOAM®, use the automatic scripts to run the cases.
                                                                                                                      395
                  snappyHexMesh guided tutorials
                                     3D Cylinder with edge refinement.
Sphere with no edge refinement Cylinder with edge refinement Cylinder with no edge refinement
•    If the geometry has sharp angles and you want to resolve those edges, you should use edge
     refinement.
•    In the left figure there is no need to use edge refinement as there are no sharp angles.
•    In the mid figure we used edge refinement to resolve the sharp angles.
•    In the right figure we did not use edge refinement, therefore we did not resolve well the sharp
     angles.
                                                                                                              396
           snappyHexMesh guided tutorials
                    3D Cylinder with edge refinement.
• How do we control curvature refinement and enable edge refinement?
• In the file snappyHexMeshDict, look for the following entry:
                           castellatedMeshControls
                           {
                                  ...
                                  ...
                                  ...
                                  ...
                                  ...
                                  ...
                                  ...
                                  ...
                                  ...
                           }                                                                                     397
 snappyHexMesh guided tutorials
                 3D Cylinder with edge refinement.
                                                   resolveFeatureAngle
                                       STL
                                                                                            398
 snappyHexMesh guided tutorials
                 3D Cylinder with edge refinement.
angle
                                                     resolveFeatureAngle
                                       STL
                                                                                            399
           snappyHexMesh guided tutorials
                    3D Cylinder with edge refinement.
• How do we control surface refinement?
• In the file snappyHexMeshDict, look for the following entry:
                        castellatedMeshControls
                        {
                                    ...
                                    ...
                                    ...
                                   ...
                                   ...
                                   ...
                                                                                              400
           snappyHexMesh guided tutorials
                      3D Cylinder with edge refinement.
• How do we create refinement regions?
• In the file snappyHexMeshDict, look for the following entry:
                geometry
                {
                    ...
                    ...
                    ...
                     ...
                                                    Dimensions of geometrical entity
                     ...
                     ...
                };
                                                                                          401
           snappyHexMesh guided tutorials
                         3D Cylinder with edge refinement.
• How do we create refinement regions?
• In the file snappyHexMeshDict, look for the following entry:
              castellatedMeshControls
              {
                   ...
                   ...
                   ...
                   refinementRegions
                   {                                   Name of the region
                         refinementBox                 created in the geometry section
                         {
                               mode inside;                  Type of refinement (inside,
                               levels ((1e15 1));            outside, or distance mode)
                         }
                   }
                                                          Refinement level
                   ...
                   ...       Distance from the surface
                   ...       A large value covers the whole region
              }
                                                                                           402
              snappyHexMesh guided tutorials
                             3D Cylinder with edge refinement.
       Explicit feature edge refinement level 0   Explicit feature edge refinement level 0
             resolveFeatureAngle 110                     resolveFeatureAngle 60
        Surface based refinement level (2 2)       Surface based refinement level (2 2)
     Explicit feature edge refinement level 0    Explicit feature edge refinement level 4
              resolveFeatureAngle 60                      resolveFeatureAngle 60
       Surface based refinement level (2 2)        Surface based refinement level (2 2)
• To control edges refinement level, you can change the value of the explicit feature
  edge refinement level.
                                                                                            404
             snappyHexMesh guided tutorials
                           3D Cylinder with edge refinement.
     Explicit feature edge refinement level 6    Explicit feature edge refinement level 0
               resolveFeatureAngle 5                       resolveFeatureAngle 5
       Surface based refinement level (2 4)        Surface based refinement level (2 4)
• To control edges refinement level, you can change the value of the explicit feature
  edge refinement level.
                                                                                            405
             snappyHexMesh guided tutorials
                            3D Cylinder with edge refinement.
      Explicit feature edge refinement level 0   Explicit feature edge refinement level 4
              resolveFeatureAngle 60                     resolveFeatureAngle 60
      Surface based refinement level (2 4)       Surface based refinement level (2 2)
• To control surface refinement level, you can change the value of the surface based
  refinement level.
• The first digit controls the global surface refinement level and the second digit
  controls the curvature refinement level.                                                  406
             snappyHexMesh guided tutorials
                            3D Cylinder with edge refinement.
      Explicit feature edge refinement level 0   Explicit feature edge refinement level 0
             resolveFeatureAngle 60                      resolveFeatureAngle 5
      Surface based refinement level (2 4)       Surface based refinement level (2 4)
• To control surface refinement due to curvature together with control based surface
  refinement level, you can change the value of resolveFeatureAngle, and surface
  based refinement level
                                                                                            407
                  snappyHexMesh guided tutorials
                                        3D Cylinder with edge refinement.
• Let us explore the dictionary surfaceFeaturesDict used by the utility
  surfaceFeatures.
• This utility will extract surface features (sharp angles) according to an angle
  criterion (includedAngle).
                                                                                  Features edges
                                                Angle criterion
  includedAngle          150;
                                                to extract features
  subsetFeatures
  {                                             Keep non-manifold edges
         nonManifoldEdges        yes;           (edges with more that 2
                                                connected faces)
                                                                                                   408
                  snappyHexMesh guided tutorials
                                        3D Cylinder with edge refinement.
• Let us explore the dictionary surfaceFeaturesDict used by the utility
  surfaceFeatures.
• This utility will extract surface features (sharp angles) according to an angle
  criterion (includedAngle).
                                                                                                                      angle
                                                Angle criterion
  includedAngle          150;
                                                to extract features
  subsetFeatures                                                                                             STL
  {                                             Keep non-manifold edges                                               includedAngle
         nonManifoldEdges        yes;           (edges with more that 2
                                                connected faces)
                                                                                                                                  409
              snappyHexMesh guided tutorials
                           3D Cylinder with edge refinement.
•   If you want to have a visual representation of the feature edges, you can use
    paraview/paraFoam.
•   Just look for the filter Feature Edges.
•   Have in mind that the angle you need to define in paraview/paraFoam is the complement of the
    angle you define in the dictionary surfaceFeaturesDict
                                                                                              410
               snappyHexMesh guided tutorials
                            3D Cylinder with edge refinement.
•   In this case we are going to generate a body fitted mesh with edge refinement. This is an
    external mesh.
•   These are the dictionaries and files that will be used.
          •   system/snappyHexMeshDict
          •   system/surfaceFeaturesDict
          •   system/meshQualityDict
          •   system/blockMeshDict
          •   constant/triSurface/surfacemesh.stl
          •   constant/triSurface/surfacemesh.eMesh
•   The file surfacemesh.eMesh is generated after using the utility surfaceFeatures, which
    reads the dictionary surfaceFeaturesDict.
•   The utility surfaceFeatures, will save a set of *.obj files with the captured edges. These files
    are located in the directory constant/extendedFeatureEdgeMesh. You can use paraview
    to visualize the *.obj files.
                                                                                                 411
           snappyHexMesh guided tutorials
                     3D Cylinder with edge refinement.
   1.   $> foamCleanTutorials
   2.   $> surfaceFeatures
   3.   $> blockMesh
   4.   $> snappyHexMesh –overwrite
   5.   $> checkMesh –latestTime
   6.   $> paraFoam
$PTOFC/101SHM/M1_cyl/C2
•   In the case directory, you will find the README.FIRST file. In this file, you will find the general instructions of
    how to run the case. In this file, you might also find some additional comments.
•   You will also find a few additional files (or scripts) with the extension .sh, namely, run_all.sh,
    run_mesh.sh, run_sampling.sh, run_solver.sh, and so on. These files can be used to run the case
    automatically by typing in the terminal, for example, sh run_solver.
•   We highly recommend you to open the README.FIRST file and type the commands in the terminal, in this
    way, you will get used with the command line interface and OpenFOAM® commands.
•   If you are already comfortable with OpenFOAM®, use the automatic scripts to run the cases.
                                                                                                                      413
snappyHexMesh guided tutorials
3D Cylinder with edge refinement and boundary layer.
                                                       414
                    snappyHexMesh guided tutorials
                   3D Cylinder with edge refinement and boundary layer.
• How do we enable boundary layer?
• In the file snappyHexMeshDict, look for the following entry:
                               ...
                               ...
                               ...
                                                                          415
          snappyHexMesh guided tutorials
          3D Cylinder with edge refinement and boundary layer.
• How do we enable boundary layer?
• In the file snappyHexMeshDict, look for the section addLayersControls:
                     addLayersControls
                     {
                           //Global parameters
                           relativeSizes true;
                           expansionRatio 1.2;
                           finalLayerThickness 0.5;
                           minThickness 0.1;
                           layers
                           {                                  Name of the surface or user-defined
                                    banana_stlSurface         patch where you want to add the
                                    {                         boundary layer mesh.
                                          nSurfaceLayers 3;
                                    }
                           }
// Advanced settings
                           ...
                           ...
                           ...
                                                                                                    416
          snappyHexMesh guided tutorials
          3D Cylinder with edge refinement and boundary layer.
• How do we control boundary layer collapsing?
• In the file snappyHexMeshDict, look for the section addLayersControls:
                          addLayersControls
                          {
                              ...
                              ...
                              ...
                              // Advanced settings
                              nGrow 0;
                                                     Increase this value to avoid BL
                              featureAngle 130;      collapsing
                              ...
                              ...
                              ...
                                                                                       417
     snappyHexMesh guided tutorials
    3D Cylinder with edge refinement and boundary layer.
                                                                               418
              snappyHexMesh guided tutorials
              3D Cylinder with edge refinement and boundary layer.
•   When the option relativeSizes is true, the boundary layer meshing is done relative to the size
    of the cells next to the surface.
•   This option requires less user intervention but can not guarantee a uniform boundary layer.
•   Also, it is quite difficult to set a desired thickness of the first layer.
                                                                                                     419
               snappyHexMesh guided tutorials
              3D Cylinder with edge refinement and boundary layer.
•   When the option relativeSizes is false, we give the actual thickness of the layers.
•   This option requires a lot user intervention but it guarantees a uniform boundary layer and the
    desired layer thickness.                                                                        420
               snappyHexMesh guided tutorials
              3D Cylinder with edge refinement and boundary layer.
•   When the option relativeSizes is true and in order to have a uniform boundary layer, we need
    to have a uniform surface refinement.
•   Nevertheless, we still do not have control on the desired thickness of the first layer.     421
               snappyHexMesh guided tutorials
              3D Cylinder with edge refinement and boundary layer.
•   To avoid boundary layer collapsing close to the corners, we can increase the value of the
    boundary layer parameter featureAngle.                                                         422
               snappyHexMesh guided tutorials
              3D Cylinder with edge refinement and boundary layer.
•   The disadvantage of setting relativeSizes to false, is that it is difficult to control the expansion
    ratio from the boundary layer meshing to the far mesh.
•   To control this transition, we can add a refinement region at the surface with distance mode.
                                                                                                       423
           snappyHexMesh guided tutorials
          3D Cylinder with edge refinement and boundary layer.
   1.   $> foamCleanTutorials
   2.   $> surfaceFeatures
   3.   $> blockMesh
   4.   $> snappyHexMesh -overwrite
   5.   $> checkMesh –latestTime
   6.   $> paraFoam
                                                                 424
                snappyHexMesh guided tutorials
               3D Cylinder with edge refinement and boundary layer.
• At the end of the meshing process you will get the following information
  regarding the boundary layer meshing:
[m] [%]
• If you want to visualize the boundary layer thickness, you can enable
  writeFlags in the snappyhexMeshDict dictionary,
         ...
         ...
         ...
         writeFlags
         (
              scalarLevels;   // write volScalarField with cellLevel for postprocessing
              layerSets;      // write cellSets, faceSets of faces in layer
              layerFields;    // write volScalarField for layer coverage
         );
         ...
         ...
         ...
                                                                                          426
          snappyHexMesh guided tutorials
          3D Cylinder with edge refinement and boundary layer.
• After creating the mesh and if you do not like the inflation layer or you want to
  try different layer parameters, you do not need to start the meshing process
  from scratch.
• To restart the meshing process from a saved state you need to save the
  intermediate steps (castellation and snapping), and then create the inflation
  layers starting from the snapped mesh.
• That is, do not use the option snappyHexMesh -overwrite.
• Also, in the dictionary controlDict remember to set the entry startFrom
  to latestTime or the time directory where the snapped mesh is saved (in
  this case 2).
• Before restarting the meshing, you will need to turn off the castellation and
  snapping options and turn on the boundary layer options in the
  snappyHexMeshDict dictionary.
                                                                                  428
           snappyHexMesh guided tutorials
           3D Cylinder with edge refinement and boundary layer.
• Remember, before restarting the meshing you will need to modify the
  snappyHexMeshDict dictionary as follows:
            castellatedMesh          false;
            snap                     false;
            addLayers                true;
• At this point, you can restart the meshing process by typing in the terminal,
        • $> snappyHexMesh
• By the way, you can restart the boundary layer mesh from a previous mesh
  with a boundary layer.
• So in theory, you an add one layer at a time, this will give you more control
  but it will require more manual work and some scripting.
                                                                                  429
                 snappyHexMesh guided tutorials
• Meshing with snappyHexMesh – Case 3.
• 3D cylinder with feature edge refinement and boundary layer using a STL
  with multiple surfaces (external mesh).
• You will find this case in the directory:
$PTOFC/101SHM/M1_cyl/C3
•   In the case directory, you will find the README.FIRST file. In this file, you will find the general instructions of
    how to run the case. In this file, you might also find some additional comments.
•   You will also find a few additional files (or scripts) with the extension .sh, namely, run_all.sh,
    run_mesh.sh, run_sampling.sh, run_solver.sh, and so on. These files can be used to run the case
    automatically by typing in the terminal, for example, sh run_solver.
•   We highly recommend you to open the README.FIRST file and type the commands in the terminal, in this
    way, you will get used with the command line interface and OpenFOAM® commands.
•   If you are already comfortable with OpenFOAM®, use the automatic scripts to run the cases.
                                                                                                                      430
                    snappyHexMesh guided tutorials
    3D Cylinder with edge refinement and boundary layer, using a STL file
                           with multiple surfaces.
     STL visualization with a single surface using paraview (the   STL visualization with multiple surfaces using paraview (each
     single surface in represented with a single color)            color corresponds to a different surface)
•   When you use a STL with multiple surfaces, you have more control over the meshing process.
•   By default, STL files are made up of one single surface.
•   If you want to create the multiple surfaces you will need to do it in the solid modeler.
•   Alternatively, you can split the STL manually or using the utility surfaceAutoPatch.
•   Loading multiple STLs is equivalent to using a STL with multiple surfaces.
                                                                                                                                   431
               snappyHexMesh guided tutorials
    3D Cylinder with edge refinement and boundary layer, using a STL file
                           with multiple surfaces.
•   When you use a STL with multiple surfaces, you have more control over the meshing process.
•   In this case, we were able to use different refinement parameters in the lateral and central
    surface patches of the cylinder.                                                             432
           snappyHexMesh guided tutorials
  3D Cylinder with edge refinement and boundary layer, using a STL file
                         with multiple surfaces.
• How do we assign different names to different surface patches?
• In the file snappyHexMeshDict, look for the following entry:
                geometry
                {
                      surfacemesh.stl
                      {
                             type triSurfaceMesh;
                             name stlSurface;
                             regions
                             {
                                       patch0                    Named region in the STL file
                                       {
                                                name surface0;   User-defined patch name
                                       }                         This is the name you need to use when setting the
                                       patch1                    boundary layer meshing
                                       {
                                                name surface1;
                                       }
                                       patch2
                                       {
                                                name surface2;
                                       }
                             }
                      }
                      ...
                      ...
                      ...
                }
                                                                                                                     433
           snappyHexMesh guided tutorials
  3D Cylinder with edge refinement and boundary layer, using a STL file
                         with multiple surfaces.
• How do we refine user defined surface patches?
• In the file snappyHexMeshDict, look for the following entry:
                castellatedMeshControls
                {
                        ...
                        ...
                        ...
                        refinementSurfaces
                        {
                               level (2 2);                            Global refinement level
                               regions
                               {
                                        patch0                         Local surface patch
                                        {
                                                 level (2 2);                     Local refinement level
                                                 patchInfo
                                                 {
                                                          type wall;                      Type of the patch.
                                                 }                                        This information is optional
                                       }
                                       ...
                                       ...
                                       ...
                               }
                       }
                       ...
                       ...
                       ...
                }
                                                                                                                         434
           snappyHexMesh guided tutorials
  3D Cylinder with edge refinement and boundary layer, using a STL file
                         with multiple surfaces.
• How do we control curvature refinement on surface patches?
• In the file snappyHexMeshDict, look for the following entry:
                castellatedMeshControls
                {
                        ...
                        ...
                        ...
                        refinementSurfaces
                        {
                               level (2 2);                            Global refinement level
                               regions
                               {
                                        patch0                         Local surface patch
                                        {
                                                 level (2 4);                      Local curvature refinement (in red)
                                                 patchInfo
                                                 {
                                                          type wall;
                                                 }
                                       }
                                       ...
                                       ...
                                       ...
                               }
                       }
                       ...
                       ...
                       ...
                }
                                                                                                                         435
           snappyHexMesh guided tutorials
  3D Cylinder with edge refinement and boundary layer, using a STL file
                         with multiple surfaces.
• How do we control curvature refinement on surface patches?
• In the file snappyHexMeshDict, look for the following entry:
                         castellatedMeshControls
                         {
                              ...
                              ...
                              ...
                              ...
                              ...
                              ...
                                                                                         436
           snappyHexMesh guided tutorials
  3D Cylinder with edge refinement and boundary layer, using a STL file
                         with multiple surfaces.
• How do we control boundary layer meshing on the surface patches?
• In the file snappyHexMeshDict, look for the following entry:
                      addLayersControls
                      {
                            //Global parameters
                            relativeSizes true;
                            expansionRatio 1.2;
                                                                        Global BL parameters
                            finalLayerThickness 0.5;
                            minThickness 0.1;
                            layers
                            {
                                    “surface.*”                         POSIX wildcards are permitted
                                    {
                                            nSurfaceLayers 5;
                                    }
                                    surface0                            Local surface patch
                                    {
                                            nSurfaceLayers 3;
                                            expansionRatio 1.0;
                                            finalLayerThickness 0.25;   Local BL parameters
                                            minThickness 0.1;
                                    }
                            }
                            //Advanced settings
                            ...
                            ...
                            ...
                      }                                                                            437
               snappyHexMesh guided tutorials
    3D Cylinder with edge refinement and boundary layer, using a STL file
                           with multiple surfaces.
1. $> cd geo
4. $> cd ..
5. $> paraview
•   The utility surfaceAutoPatch will read the original STL file (geo.stl), and it will find the
    patches using an angle criterion of 130 (similar to the angle criterion used with the utility
    surfaceFeatures). It writes the new STL geometry in the file output.stl.
•   By the way, it is better to create the STL file with multiple surfaces directly in the solid modeler.
•   FYI, there is an equivalent utility for meshes, autoPatch. So if you forgot to define the
    patches, this utility will automatically find the patches according to an angle criterion.          438
            snappyHexMesh guided tutorials
  3D Cylinder with edge refinement and boundary layer, using a STL file
                         with multiple surfaces.
• If you open the file output.stl, you will notice that there are three
  surfaces defined in the STL file. The different surfaces are defined in by the
  following sections:
      solid patch0
           …                   Surface patch 1   •   The name of the solid sections are
                                                     automatically given by the utility
      endsolid patch0
                                                     surfaceAutoPatch.
      solid patch1
                                                 •   The convention is as follows: patch0,
           …                   Surface patch 2
                                                     patch1, patch2, … patchN.
      endsolid patch1
endsolid patch2
                                                                                             439
           snappyHexMesh guided tutorials
  3D Cylinder with edge refinement and boundary layer, using a STL file
                         with multiple surfaces.
    1.   $> foamCleanTutorials
    2.   $> surfaceFeatures
    3.   $> blockMesh
    4.   $> snappyHexMesh -overwrite
    5.   $> checkMesh –latestTime
                                                                          440
           snappyHexMesh guided tutorials
  3D Cylinder with edge refinement and boundary layer, using a STL file
                         with multiple surfaces.
• This case is ready to run using the solver simpleFoam. But before running,
  you will need to set the boundary and initial conditions.
• You will need to manually modify the file constant/polyMesh/boundary
• Remember:
   • Base type boundary conditions are defined in the file boundary located
     in the directory constant/polyMesh.
   • Numerical type boundary conditions are defined in the field variables
     files located in the directory 0 or the time directory from which you want
     to start the simulation (e.g. U, p).
   • The name of the base type boundary conditions and numerical type
     boundary conditions needs to be the same.
   • Also, the base type boundary condition needs to be compatible with the
     numerical type boundary condition.
                                                                              441
           snappyHexMesh guided tutorials
  3D Cylinder with edge refinement and boundary layer, using a STL file
                         with multiple surfaces.
1. $> sh run_all.sh
                                                                                  442
                 snappyHexMesh guided tutorials
$PTOFC/101SHM/M1_cyl/C4
•   In the case directory, you will find the README.FIRST file. In this file, you will find the general instructions of
    how to run the case. In this file, you might also find some additional comments.
•   You will also find a few additional files (or scripts) with the extension .sh, namely, run_all.sh,
    run_mesh.sh, run_sampling.sh, run_solver.sh, and so on. These files can be used to run the case
    automatically by typing in the terminal, for example, sh run_solver.
•   We highly recommend you to open the README.FIRST file and type the commands in the terminal, in this
    way, you will get used with the command line interface and OpenFOAM® commands.
•   If you are already comfortable with OpenFOAM®, use the automatic scripts to run the cases.
                                                                                                                      443
            snappyHexMesh guided tutorials
                                    2D Cylinder
From 3D To 2D
• To generate a 2D mesh using snappyHexMesh, we need to start from a 3D. After all,
  snappyHexMesh is a 3D mesher.
• To generate a 2D mesh (and after generating the 3D mesh), we use the utility
  extrudeMesh.
• The utility extrudeMesh works by projecting a face into a mirror face. Therefore,
  the faces need to parallel.                                                         444
                   snappyHexMesh guided tutorials
                                                2D Cylinder
                                            Geometry width
                                   FACE 1
•   At most, the input geometry and the background mesh need to have the same width.
•   If the input geometry is larger than the background mesh, it will be automatically cut by the faces
    of the background mesh.
•   In this case, the input geometry will be cut by the two lateral patches of the background mesh.
•   If you want to take advantage of symmetry in 3D, you can cut the geometry in half using one of
    the faces of the background mesh.
•   When dealing with 2D
•   Extracting the features edges is optional for the 2D geometry extremes, but it is recommended if
    there are internal edges that you want to resolve.
                                                                                                    445
          snappyHexMesh guided tutorials
                                      2D Cylinder
• How do we create the 2D mesh?
• After generating the 3D mesh, we use the utility extrudeMesh.
• This utility reads the extrudeMeshDict,
constructFrom patch;
               sourceCase “.”
               sourcePatches (minZ);                Name of source patch
               extrudeModel linearNormal
                                                    Number of layers to use in the linear extrusion.
               nLayers 1;
                                                    As this is a 2D case we must use 1 layer
               linearNormalCoeffs
               {
                                                    Thickness of the extrusion.
                     thickness 1;
                                                    It is highly recommended to use a value of 1
               }
               mergeFaces false;
                                                                                                   446
             snappyHexMesh guided tutorials
                                    2D Cylinder
     1.   $> foamCleanTutorials
     2.   $> blockMesh
     3.   $> snappyHexMesh –overwrite
     4.   $> extrudeMesh
     5.   $> checkMesh –latestTime
     6.   $> paraFoam
                                                                                                                      448
                 snappyHexMesh guided tutorials
$PTOFC/101SHM/M2_mixing_elbow
•   In the case directory, you will find the README.FIRST file. In this file, you will find the general instructions of
    how to run the case. In this file, you might also find some additional comments.
•   You will also find a few additional files (or scripts) with the extension .sh, namely, run_all.sh,
    run_mesh.sh, run_sampling.sh, run_solver.sh, and so on. These files can be used to run the case
    automatically by typing in the terminal, for example, sh run_solver.
•   We highly recommend you to open the README.FIRST file and type the commands in the terminal, in this
    way, you will get used with the command line interface and OpenFOAM® commands.
•   If you are already comfortable with OpenFOAM®, use the automatic scripts to run the cases.
                                                                                                                      449
snappyHexMesh guided tutorials
               Mixing elbow.
                castellatedMeshControls
                {
                     ...
                     ...
                     ...
                     refinementRegions
                     {
                           mixing_elbow                          Name of surface
                           {
                                mode distance;                   Refinement using distance mode
                                levels ((1e-4 1));
                           }
                     }
                                                                          452
            snappyHexMesh guided tutorials
                                 Mixing elbow.
• At this point, we are going to work in parallel (but you can work in serial as
  well).
• To generate the mesh, in the terminal window type:
    1.   $> foamCleanTutorials
    2.   $> surfaceFeatures
    3.   $> blockMesh
    4.   $> decomposePar
    5.   $> mpirun -np 4 snappyHexMesh –parallel –overwrite
    6.   $> mpirun -np 4 checkMesh –parallel –latestTime
    7.   $> reconstructParMesh -constant
    8.   $> paraFoam
                                                                                   453
              snappyHexMesh guided tutorials
                                         Mixing elbow.
•   So what did we do?
          •   Step 4: we distribute the mesh among the processors we want to use.
          •   Step 5 and 6: we run in parallel.
          •   Step 7: we put back together the decomposed mesh.
          •   Step 8: we visualize the reconstructed mesh.
                                                                                         455
             snappyHexMesh guided tutorials
                                     Mixing elbow.
•   Empty patches are no problem, they remain from the background mesh.
•   To erase the empty patches, you can do it manually (you will need to modify the file
    boundary), or you can use the utility createPatch as follows (the utility runs in
    parallel):
         •   $> createPatch -overwrite
•   The surface patch pipe was created in the geometry section of the dictionary
    snappyHexMeshDict.
•   The patches mixing_elbow_outlet, mixing_elbow_inlet1 and
    mixing_elbow_inlet2 were created automatically by snappyHexMesh.
•   You have the choice of giving the names of the patches yourself or letting
    snappyHexMesh assign the names automatically.
•   Remember, when creating the boundary layer mesh, these are the names you need
    to use to assign the layers.
                                                                                           456
                        snappyHexMesh guided tutorials
                                                                Mixing elbow.
•       The mesh used in the previous case was a STL with multiple surfaces.
•       In you do not create the regions in the geometry section of the dictionary
        snappyHexMeshDict, snappyHexMesh will automatically assign the names of the
        surface patches as follows:
                                                                                 system/surfaceFeaturesDict
                                                                                …
                         •     mixing_elbow_outlet                              …
                         •     mixing_elbow_inlet1                              geometry
                                                                                {
                                                                                      surfacemesh.stl
                         •     mixing_elbow_inlet2                                    {
                                                                                             type triSurfaceMesh;
                                                                                             name mixing_elbow;
                                                                                             regions
                                                                                             {
                                                                                                     pipe          NOTE 1
                                                                                                     {
                                                                                      NOTE 2                name pipe;
                                                                                                     }
                                                                                             }
                                                                                       }
    NOTE 1:
                                                                                };
    This is the name of the region or surface patch in the STL file
                                                                                …
    NOTE 2:
                                                                                …
    User-defined patch name. This is the final name of the patch.
                                                                                                                            457
             snappyHexMesh guided tutorials
                                   Mixing elbow.
•   The mesh used in the previous case was a STL with multiple surfaces.
•   In you do not create the regions in the geometry section of the dictionary
    snappyHexMeshDict, snappyHexMesh will automatically assign the names of the
    surface patches as follows:
                                                constant/triSurface/surfacemesh.stl
             •   mixing_elbow_outlet
                                                      solid outlet
             •   mixing_elbow_inlet1                          …
                                                              …
                                                              …
             •   mixing_elbow_inlet2                  solid outlet
                                                      solid inlet1
                                                              …
                                                              …
                                                              …
                                                      solid inlet1
                                                      solid inlet2
                                                              …
                                                              …
                                                              …
                                                      solid inlet2
                                                                                      458
           snappyHexMesh guided tutorials
                                 Mixing elbow.
• The mesh used in the previous case was a STL with multiple surfaces.
• In the directory geometry, you fill find the file allss.stl, this STL has one
  single surface.
• Try to use this STL file to generate the mesh.
• You will notice that the final mesh has only one patch, namely
  mixing_elbow (or whatever name you chose).
• Also, it is not possible to have local control on the mesh refinement and
  boundary layer meshing.
• You will also face the conundrum that as there is only one surface patch, it is
  not possible to assign boundary conditions.
                                                                               459
             snappyHexMesh guided tutorials
                                     Mixing elbow.
•   To solve the problem of the single surface patch, you can use the utility autoPatch.
    To do so, you can proceed as follows:
         •   $> autoPatch 60 -overwrite
•   The option -overwrite, will copy the new mesh in the directory
    constant/polyMesh.
•   The utility autoPatch will use an angle criterion to find the patches, and will assign
    the name auto0, auto1, auto2 and auto3 to the new patches.
•   The angle criterion is similar to that of the utility surfaceFeatures.
•   The only difference is that it uses the complement of the angle. So, the smaller the
    angle the more patches it will find.
•   The naming convention is autoN, where N is the patch number.
•   Remember, autoPatch will manipulate the mesh located in the directory
    constant/polyMesh.
•   FYI, autoPatch does not un in parallel.
                                                                                           460
                snappyHexMesh guided tutorials
                                                   Exercises
•   To get a feeling of the includedAngle value, try to change the value in the dictionary
    surfaceFeaturesDict.
•   Remember the higher the includedAngle value, the more features you will capture.
•   In the dictionary snappyHexMeshDict, change the value of resolveFeatureAngle (try to use a lower value),
    and check the mesh quality in the intersection between both pipes.
•   In the castellatedMeshControls section, try to disable or modify the distance refinement of the
    mixing_elbow region (refinementRegions).
•   What difference do you see in the output?
•   Starting from the body fitted mesh, add 3 inflation layers at the walls (save the intermediate step).
•   Try to add local surface refinement at the surface patch inlet2 (look at the STL file
    constant/triSurface/surfacemesh_multi.stl).
•   Using paraview, extract the feature edge at the joint section of the pipes. Then, try to add local refinement at
    this feature edge.
•   Try to add curvature refinement at the feature edge extracted from the surface patch inlet1.
                                                                                                                   461
                snappyHexMesh guided tutorials
                                                 Exercises
•   Use the STL file with a single surface (surfacemesh_single.stl) and generate the same mesh, do not
    add inflation layers.
     •   Use the utility autopatch to split the mesh in different surface patches. To get a feeling on how to use
         this utility, use different angle values. Try to get four surface patches.
     •   After splitting the mesh in four surface patches, rename the boundary patches using the utility
         createPatch.
     •   After renaming the boundary patches, change the type of each one using the utility foamDictionary.
     •   Starting from the body fitted mesh, add 3 inflation layers at the walls (do not save the intermediate step).
     •   Hints: if you do not know how to use the utilities createPatch and foamDictionary, look at the
         script file run_mesh_single_surface.sh
•   After generating the mesh, setup a simple incompressible simulation (with no turbulence model).
     •   Set the inlet velocity to 1 at both inlet patches and use a dynamic viscosity value equal to 0.01. Run the
         simulation in steady and unsteady mode.
                                                                                                                  462
                 snappyHexMesh guided tutorials
$PTOFC/101SHM/M4_ahmed
•   In the case directory, you will find the README.FIRST file. In this file, you will find the general instructions of
    how to run the case. In this file, you might also find some additional comments.
•   You will also find a few additional files (or scripts) with the extension .sh, namely, run_all.sh,
    run_mesh.sh, run_sampling.sh, run_solver.sh, and so on. These files can be used to run the case
    automatically by typing in the terminal, for example, sh run_solver.
•   We highly recommend you to open the README.FIRST file and type the commands in the terminal, in this
    way, you will get used with the command line interface and OpenFOAM® commands.
•   If you are already comfortable with OpenFOAM®, use the automatic scripts to run the cases.
                                                                                                                      463
             snappyHexMesh guided tutorials
                                      Ahmed body
                                                                                                  465
                    Roadmap
1.   Meshing preliminaries
2.   What is a good mesh?
3.   Mesh quality assessment in OpenFOAM®
4.   Mesh generation using blockMesh.
5.   Mesh generation using snappyHexMesh.
6.   snappyHexMesh guided tutorials.
7.   Mesh conversion
8.   Geometry and mesh manipulation utilities
                                                466
                                 Mesh conversion
•   OpenFOAM® gives users a lot of flexibility when it comes to meshing.
•   You are not constrained to use OpenFOAM® meshing tools.
•   To convert a mesh generated with a third-party software to OpenFOAM® format, you can use
    the OpenFOAM® mesh conversion utilities.
•   If your format is not supported, you can write your own conversion tool.
•   By the way, many of the commercially available meshers can save the mesh in OpenFOAM®
    format or in a compatible format.
•   In the directory $PTOFC/mesh_conversion_sandbox you will find a few meshes generated
    using the most popular third-party mesh generation applications.
•   Feel free to play with these meshes.
•   In the README.FIRST file of each case, you will find the instructions of how to convert the
    mesh.
•   Remember to always check the file boundary after converting the mesh. You
    will need to change the name and type of the surface patches according to what
    you would intent to do.
•   Also, to convert the mesh you need to be in the top level of the case directory,
    and you need to give to the conversion utility the path (absolute or relative) of
    the mesh to be converted.
                                                                                                  467
                           Mesh conversion
• In the directory $FOAM_UTILITIES/mesh/conversion you will find the source
  code for the mesh conversion utilities:
   • ansysToFoam                            • kivaToFoam
   • cfx4ToFoam                             • mshToFoam
   • datToFoam                              • netgenNeutralToFoam
   • fluent3DMeshToFoam                     • Optional/ccm26ToFoam
   • fluentMeshToFoam                       • plot3dToFoam
   • foamMeshToFluent                       • sammToFoam
   • foamToStarMesh                         • star3ToFoam
   • foamToSurface                          • star4ToFoam
   • gambitToFoam                           • tetgenToFoam
   • gmshToFoam                             • vtkUnstructuredToFoam
   • ideasUnvToFoam                         • writeMeshObj
• Take your time and read the instructions/comments contained in the source code of
  the mesh conversion utilities so you can understand how to use these powerful tools.
                                                                                    468
                                      Mesh conversion
$PTOFC/mesh_conversion_sandbox/M1_mixing_elbow_salome
•   In the case directory, you will find the README.FIRST file. In this file, you will find the general instructions of
    how to run the case. In this file, you might also find some additional comments.
•   You will also find a few additional files (or scripts) with the extension .sh, namely, run_all.sh,
    run_mesh.sh, run_sampling.sh, run_solver.sh, and so on. These files can be used to run the case
    automatically by typing in the terminal, for example, sh run_solver.
•   We highly recommend to open the README.FIRST file and type the commands in the terminal, in this way
    you will get used with the command line interface and OpenFOAM® commands.
•   If you are already comfortable with OpenFOAM®, use the automatic scripts to run the cases.
                                                                                                                      469
                            Mesh conversion
                      Case 1. Mixing elbow (internal mesh).
    1.   $> foamCleanTutorials
    2.   $> foamCleanPolyMesh
    3.   $> ideasUnvToFoam ../../meshes_and_geometries/salome_elbow3d/Mesh_1.unv
    4.   $> checkMesh
    5.   $> paraFoam
•   Remember to always check the file boundary after converting the mesh.
•   To convert the mesh, you need to be in the top level of the case directory, and you
    need to give the path (absolute or relative) of the mesh to be converted.
                                                                                          470
                                       Mesh conversion
                             Case 1. Mixing elbow (internal mesh).
• ideasUnvToFoam output.
Create time
      Processing tag:2411
      Starting reading points at line 3.
      Read 31136 points.
      Processing tag:2412
      Starting reading cells at line 62278.
      First occurrence of element type 11 for cell 1 at line 62279
      First occurrence of element type 41 for cell 361 at line 63359
      First occurrence of element type 111 for cell 20933 at line 104503
      Read 151064 cells and 20572 boundary faces.                                 Internal cells and boundary faces read
      Processing tag:2467
      Starting reading patches at line 406633.
      For group 1 named pipe trying to read 19778 patch face indices.
      For group 2 named inlet1 trying to read 358 patch face indices.
      For group 3 named inlet2 trying to read 78 patch face indices.
      For group 4 named outlet trying to read 358 patch face indices.
End
                                                                                                                           471
                                     Mesh conversion
                             Case 1. Mixing elbow (internal mesh).
• checkMesh output.
 Mesh stats
     points:             31136
     faces:              312414
     internal faces:     291842
     cells:              151064
     faces per cell:     4
     boundary patches:   4
     point zones:        0
     face zones:         0
     cell zones:         0
 Checking topology...
     Boundary definition OK.
     Cell to face addressing OK.
     Point usage OK.
     Upper triangular ordering OK.
     Face vertices OK.
     Number of regions: 1 (OK).
                                                                     472
                                   Mesh conversion
                           Case 1. Mixing elbow (internal mesh).
• checkMesh output.
 Checking geometry...
     Overall domain bounding box (0 -0.414214 -0.5) (5 5 0.5)
     Mesh has 3 geometric (non-empty/wedge) directions (1 1 1)
     Mesh has 3 solution (non-empty) directions (1 1 1)
     Boundary openness (-1.0302e-17 -6.17232e-17 -1.77089e-16) OK.
     Max cell openness = 2.32045e-16 OK.
     Max aspect ratio = 4.67245 OK.
     Minimum face area = 0.000286852. Maximum face area = 0.010949. Face area magnitudes OK.
     Min volume = 2.74496e-06. Max volume = 0.00035228. Total volume = 6.75221. Cell volumes OK.
     Mesh non-orthogonality Max: 54.2178 average: 15.1295
     Non-orthogonality check OK.
     Face pyramids OK.
     Max skewness = 0.649359 OK.
     Coupled point location match (average 0) OK.
End
                                                                                                   473
                                        Mesh conversion
                               Case 1. Mixing elbow (internal mesh).
• The boundary file.
                                                                                              474
                                  Mesh conversion
                          Case 1. Mixing elbow (internal mesh).
• The boundary file.
 4
 (
     pipe
     {
            type
            nFaces
                        patch;
                        19778;
                                              Base type of the boundary patches
            startFace   291842;
     }
     inlet1
     {
                                              • In this case, the utility automatically
         type           patch;                  assigned the base type patch to all
         nFaces         358;
         startFace      311620;                 boundary patches.
     }
     inlet2
     {
                                              • Feel free to change the base type
         type
         nFaces
                        patch;
                        78;
                                                according to your needs.
         startFace      311978;
     }                                        • In this case, it will be wise to change
     outlet
     {
                                                the base type of patch pipe to wall.
         type           patch;
         nFaces         358;
         startFace      312056;
     }
 )
                                                                                          475
                                    Mesh conversion
                                                 Exercises
•   Remember, you can change the name and type of the boundary patches manually, but as we want to do
    things automatically, we will use the utilities createPatch and foamDictionary
     •   After converting the mesh to OpenFOAM® format, rename the boundary patches using the utility
         createPatch.
     •   After converting the mesh to OpenFOAM® format, change the type of each boundary patch using the
         utility foamDictionary.
•   After converting the mesh to OpenFOAM® format, add 5 inflation layers at the walls (do not save the
    intermediate step).
•   Check the mesh quality before and after adding the inflation layers.
•   After generating the mesh, setup a simple incompressible simulation (with no turbulence model).
     •   Set the inlet velocity to 1 at both inlet patches and use a dynamic viscosity value equal to 0.01. Run the
         simulation in steady and unsteady mode.
                                                                                                                 476
                    Roadmap
1.   Meshing preliminaries
2.   What is a good mesh?
3.   Mesh quality assessment in OpenFOAM®
4.   Mesh generation using blockMesh.
5.   Mesh generation using snappyHexMesh.
6.   snappyHexMesh guided tutorials.
7.   Mesh conversion
8.   Geometry and mesh manipulation utilities
                                                477
    Geometry and mesh manipulation utilities
• First of all, by mesh manipulation we mean modifying a valid OpenFOAM®
  mesh.
• These modifications can be scaling, rotation, translation, mirroring,
  topological changes, mesh refinement and so on.
• In the directory $FOAM_UTILITIES/mesh/manipulation you will find the
  mesh manipulation utilities. Just to name a few:
       • autoPatch                        • rotateMesh
       • checkMesh                        • setSet
       • createBaffles                    • splitMesh
       • mergeMeshes                      • splitMeshRegions
       • mergerOrSplitBaffles             • stitchMesh
       • mirrorMesh                       • subsetMesh
       • polyDualMesh                     • topoSet
       • refineMesh                       • transformPoints
       • renumberMesh
                                                                           478
    Geometry and mesh manipulation utilities
• In the directory $FOAM_UTILITIES/mesh/manipulation you will find the
  following mesh manipulation utilities.
• Inside each utility directory you will find a *.C file with the same name as the
  directory. This is the main file, where you will find the top-level source code and a
  short description of the utility.
• For instance, in the directory checkMesh, you will find the file checkMesh.C, which
  is the source code of the utility checkMesh. In the source code you will find the
  following description:
            Usage
              - checkMesh [OPTION]
              \param -allGeometry \n
              Checks all (including non finite-volume specific) geometry
              \param -allTopology \n
              Checks all (including non finite-volume specific) addressing
              \param -meshQuality \n
              Checks against user defined (in \a system/meshQualityDict) quality settings
    • surfaceAdd                         • surfaceMeshConvert
    • surfaceAutoPatch                   • surfaceMeshExport
    • surfaceBooleanFeatures             • surfaceMeshTriangulate
    • surfaceCheck                       • surfaceOrient
    • surfaceConvert                     • surfaceSplitByPatch
    • surfaceFeatureConvert              • surfaceSubset
    • surfaceFeatures                    • surfaceToPatch
    • surfaceInertia                     • surfaceTransformPoints
                                                                          480
    Geometry and mesh manipulation utilities
• In the directory $FOAM_UTILITIES/surface you will find the following surface
  manipulation utilities.
• Inside each utility directory you will find a *.C file with the same name as the
  directory. This is the main file, where you will find the top-level source code and a
  short description of the utility.
• For instance, in the directory surfaceTransformPoints, you will find the file
  surfaceTransformPoints.C, which is the source code of the utility
  surfaceTransformPoints. In the source code you will find the following
  description:
                                                                                          481
     Geometry and mesh manipulation utilities
$PTOFC/mesh_quality_manipulation/M5_ahmed_body_transform
•   In the case directory, you will find the README.FIRST file. In this file, you will find the general instructions of
    how to run the case. In this file, you might also find some additional comments.
•   You will also find a few additional files (or scripts) with the extension .sh, namely, run_all.sh,
    run_mesh.sh, run_sampling.sh, run_solver.sh, and so on. These files can be used to run the case
    automatically by typing in the terminal, for example, sh run_solver.
•   We highly recommend to open the README.FIRST file and type the commands in the terminal, in this way
    you will get used with the command line interface and OpenFOAM® commands.
•   If you are already comfortable with OpenFOAM®, use the automatic scripts to run the cases.
                                                                                                                      482
    Geometry and mesh manipulation utilities
          Geometry manipulation in OpenFOAM®
• We will now manipulate a STL geometry. In the terminal type:
  1.    $> foamCleanTutorials
  2.    $> surfaceMeshInfo ./constant/triSurface/ahmed_body.stl
  3.    $> surfaceCheck ./constant/triSurface/ahmed_body.stl
        $> surfaceTransformPoints -rollPitchYaw '(0 0 15)’
  4.       ./constant/triSurface/ahmed_body.stl rotated.stl
        $> surfaceTransformPoints -translate '(0 0.12 0)'
  5.       ./constant/triSurface/ahmed_body.stl   translated.stl
        $> surfaceTransformPoints -scale '(0.9 1.1 1.3)'
  6.       ./constant/triSurface/ahmed_body.stl   scaled.stl
        $> surfaceInertia -density 2700 –noFunctionObjects
  7.       ./constant/triSurface/ahmed_body.stl
        $> surfaceOrient ./constant/triSurface/ahmed_body_wrong_normals.stl
  8.       out.stl ‘(1e10 1e10 1e10)’
                                                                              483
     Geometry and mesh manipulation utilities
             Geometry manipulation in OpenFOAM®
•   In step 2 we use the utility surfaceMeshInfo to get general information about the STL (such
    as number of faces and so on).
•   In step 3 we use the utility surfaceCheck to check the STL file.
•   In step 4 we use the utility surfaceTransformPoints to rotate the STL. We read in the STL
    ./constant/triSurface/ahmed_body.stl and we write out the STL rotated.stl
•   In step 5 we use the utility surfaceTransformPoints to translate the STL. We read in the
    STL ./constant/triSurface/ahmed_body.stl and we write out the STL
    translated.stl
•   In step 6 we use the utility surfaceTransformPoints to scale the STL. We read in the STL
    ./constant/triSurface/ahmed_body.stl and we write out the STL scaled.stl
•   In step 7 we use the utility surfaceInertia to compute the inertia of the STL. We read in the
    STL ./constant/triSurface/ahmed_body.stl. Notice that we need to give a reference
    density value.
•   In step 8 we use the utility surfaceOrient to orient the normals of the STL in the same way.
    We read in the STL ./constant/triSurface/ahmed_body_wrong_normals.stl and we
    write out the STL out.stl. Notice that we give an outside point or ‘(1e10 1e10 1e10)’, if
    this point is outside the STL all normals will be oriented outwards, if the point is inside the STL
    all normals will be oriented inwards.
                                                                                                     484
     Geometry and mesh manipulation utilities
             Geometry manipulation in OpenFOAM®
•   Pay particular attention to step 8.
•   We already have seen that snappyHexMesh computes surface angles using the surface
    normals as a reference, so it is extremely important to have the normals oriented in the same
    way and preferably outwards.
                                                                                                      485
        Geometry and mesh manipulation utilities
                     Geometry manipulation in OpenFOAM®
•    To plot the normals in paraview/paraFoam you can use the filter Normal Glyphs
       Select the Normal Glyphs from the filter menu
                                                                                     486
     Geometry and mesh manipulation utilities
$PTOFC/mesh_quality_manipulation/M7_cylinder_transform
•   In the case directory, you will find the README.FIRST file. In this file, you will find the general instructions of
    how to run the case. In this file, you might also find some additional comments.
•   You will also find a few additional files (or scripts) with the extension .sh, namely, run_all.sh,
    run_mesh.sh, run_sampling.sh, run_solver.sh, and so on. These files can be used to run the case
    automatically by typing in the terminal, for example, sh run_solver.
•   We highly recommend to open the README.FIRST file and type the commands in the terminal, in this way
    you will get used with the command line interface and OpenFOAM® commands.
•   If you are already comfortable with OpenFOAM®, use the automatic scripts to run the cases.
                                                                                                                      487
     Geometry and mesh manipulation utilities
                   Mesh manipulation in OpenFOAM®
•   We will now manipulate a mesh. In the terminal type:
    1.     $> foamCleanTutorials
    2.     $> blockMesh
    3.     $> transformPoints -rollPitchYaw '(0 0 90)'
    4.     $> transformPoints -scale '(0.01 0.01 0.01)'
    5.     $> transformPoints -translate '(0 0 1)'
    6.     $> createPatch -noFunctionObjects –overwrite
    7.     $> checkMesh
    8.     $> paraFoam
•   In step 3 we use the utility transformPoints to rotate the mesh. We rotate the mesh by 90° about the Z
    axis.
•   In step 4 we use the utility transformPoints to scale the mesh. We scale the mesh by a factor of '(0.01
    0.01 0.01)'.
•   In step 5 we use the utility transformPoints to translate the mesh. We translate the mesh by the vector
    '(0 0 1)'.
•   In step 6 we use the utility createPatch to rename the patches of the mesh. This utility reads the dictionary
    system/createPatchDict. Instead of using the utility createPatch we could have modified the
    boundary file directly.
•   This case is ready to run using the solver buoyantBoussinesqPimpleFoam.                                     488
Geometry and mesh manipulation utilities
       Mesh manipulation in OpenFOAM®
Original mesh
                      490
                  Roadmap
1. Running in parallel
                            491
                                  Running in parallel
•   First of all, to know how many processors/cores you have available in your computer, type in the
    terminal:
             •   $> lscpu
•   The output for this particular workstation is the following:
     Architecture:          x86_64
     CPU op-mode(s):        32-bit, 64-bit
     Byte Order:            Little Endian
                                                                                Total number of cores available after
     CPU(s):                24
                                                                                hyper threading (virtual cores)
     On-line CPU(s) list:   0-23
     Thread(s) per core:    2
     Core(s) per socket:    6                                                  Number of threads per core (hyper threading)
     Socket(s):             2
     NUMA node(s):          2
     Vendor ID:             GenuineIntel                                     Number of cores per socket or physical
     CPU family:            6                                                processor
     Model:                 44
     Model name:            Intel(R) Xeon(R) CPU   X5670 @ 2.93GHz
     Stepping:              2                                                Number of sockets (physical processors)
     CPU MHz:               1600.000
     CPU max MHz:           2934.0000
     CPU min MHz:           1600.0000
     BogoMIPS:              5851.91
                                                                              Total number of physical cores
     Virtualization:        VT-x
                                                                                            =
     L1d cache:             32K
                                                                     Number of cores per socket X Number of sockets
     L1i cache:             32K
     L2 cache:              256K
     L3 cache:              12288K                                   Total number of physical cores = 6 X 2 = 12 cores
     NUMA node0 CPU(s):     0-5,12-17
     NUMA node1 CPU(s):     6-11,18-23
• To take full advantage of the hardware, we use the maximum number of physical
  cores (12 physical cores in this case) when running in parallel.
• If you use the maximum number of virtual cores, OpenFOAM® will run but it will be
  slower in comparison to running with the maximum number of physical cores (or even
  less cores).
• Same rule applies when running in clusters/super computers, so always read the
  hardware specifications to know the limitations.
                                                                                   493
                                  Running in parallel
                                  Why use parallel computing?
          Thanks to parallel computing we can solve bigger problems (scalability). A single computer has limited
          physical memory, many computers interconnected have access to more memory (distributed memory).
          A single computer or processor can only do one thing at a time. Multiple processors or computing
          resources can do many things simultaneously.
          Run faster (speed-up) and increase your productivity, with the potential of saving money in the design
          process.
• Save money:
          In theory, throwing more resources at a task will shorten its time to completion, with potential cost
          savings. Parallel computers can be built from cheap, commodity components.
          Both physical and practical reasons pose significant constraints to simply building ever faster serial
          computers (e.g, transmission speed, CPU clock rate, limits to miniaturization, hardware cooling).
                                                                                                                   494
                                  Running in parallel
                               Speed-up and scalability example
• In the context of high-performance computing (HPC), there are two common metrics that measure the
  scalability of the application:
      • Strong scaling (Amdahl’s law): which is defined as how the solution time varies with the number of
         processors for a fixed problem size (number of cells in CFD)
      • Weak scaling (Gustafson’s law): which is defined as how the solution time varies with the number of
         processors for a fixed problem size per processor (or increasing the problem size with a fix number of
         processors).
• In this example, when we reach 12 cores inter-processor communication slow-downs the computation. But if we
  increase the problem size for a fix number of processors, we will increase the speed-up.
• The parallel case with 1 processor runs slower than the serial case due to the extra overhead when calling the
  MPI library.                                                                                                  495
                           Running in parallel
•   The method of parallel computing used by OpenFOAM® is known as domain
    decomposition, in which the geometry and associated fields are broken into pieces
    and distributed among different processors.
                                                                                           497
                      Running in parallel
To run OpenFOAM® in parallel you will need to:
•   In this example, we are subdividing the domain in 128 subdomains, therefore we should have
    128 physical cores available.
•   The main goal of domain decomposition is to minimize the inter-processors communication and
    the processor workload.
                                                                                                 499
                              Running in parallel
                             Domain Decomposition Methods
•   These are the decomposition methods available in OpenFOAM® 8. To name a few:
          •   hierarchical
          •   manual
          •   metis
          •   multiLevel
          •   none                                  We highly recommend you to use this method.
                                                    The only input that requires from the user is
          •   scotch                                the number of subdomains/cores. This method
                                                    attempts to minimize the number of processor
          •   simple
                                                    boundaries.
          •   structured
•   If you want more information about each decomposition method, just read the source code:
          •   $WM_PROJECT_DIR/src/parallel/decompose/
                                                                                                500
                                 Running in parallel
                      Running in parallel – Gathering all together
decomposePar
•   Inside each processorN directory you will have the mesh information, boundary conditions,
    initial conditions, and the solution for that processor.
                                                                                                501
                             Running in parallel
                     Running in parallel – Gathering all together
•   After decomposing the mesh, we can run in parallel using MPI.
•   The number of processors to use or <NPROCS>, needs to be the same as the number of
    partitions (numberOfSubdomains).
•   Do not forget to use the flag –parallel.
                                                                                                        502
      Running in parallel
Running in parallel – Gathering all together
              •   In the decomposed case, you will find the mesh
                  information, boundary conditions, initial conditions, and
                  the solution for every processor.
              •   The information is inside the directory processorN
                  (where N is the processor number).
reconstructPar
              •   When you reconstruct the case, you glue together all the
                  information contained in the decomposed case.
              •   All the information (mesh, boundary conditions, initial
                  conditions, and the solution), is transfer to the original
                  case folder (polyMesh and time solution directories).
                                                                               503
                              Running in parallel
                     Running in parallel – Gathering all together
•   Summarizing, to run in parallel we proceed in the following way:
    1.    $> decomposePar
    2.    $> mpirun –np <NPROCS> <application/utility> –parallel
    3.    $> reconstructPar
•   You can do the post-processing and visualization on the decomposed case or reconstructed
    case. We are going to address this later on.
•   If you are dealing with moving bodies where the mesh topology is changed or if you are using
    AMR, you will need to use reconstructParMesh before reconstrucPar.
                                                                                                          504
                                          Running in parallel
                           Kelvin Helmholtz instability in a coarse mesh
                                                                                                       Mesh size
                                                           Processors   Clock time (seconds)
                                                                                               in x, y, and z directions
                   Volume fraction
     www.wolfdynamics.com/wiki/kelvin_helmholtz/ani1.gif
•   The traditional way is to first reconstruct the case and then do the post-processing and
    visualization on the reconstructed case.
•   To do so, we type in the terminal:
    1.   $> reconstructPar
    2.   $> paraFoam
•   Step 1 reconstruct the case. Remember, you can choose to reconstruct all the time steps, the
    last time step or a range of time steps.
•   In step 2, we use paraFoam to visualize the reconstructed case.
                                                                                               506
                              Running in parallel
                              Visualization of a parallel case
•   An alternative way to visualize the solution, is by proceeding in the following way
          •   $> paraFoam –builtin
                                                                                            507
                                Running in parallel
                                Visualization of a parallel case
•   Both of the previous methods are valid.
•   When we use the option –builtin with paraFoam, we have the option to work on the
    decomposed case directly. In other words, we do not need to reconstruct the case.
•   This option is also faster than running paraFoam with no flags.
•   But wait, there is a third option.
•   The third option consist in post-processing each decomposed domain individually.
•   To load all processor directories, you will need to manually create the file
    processorN.OpenFOAM (where N is the processor number) in each processor folder.
•   After creating all processorN.OpenFOAM files, you can launch paraFoam and load each file
    (the processorN.OpenFOAM files).
•   As you can see, this option requires more input from the user.
                                                                                           508
                              Running in parallel
                                Decomposing big meshes
•   One final word, the utility decomposePar does not run in parallel.
•   So, it is not possible to distribute the mesh among different computing nodes to do the
    partitioning in parallel.
•   If you need to partition big meshes, you will need a computing node with enough memory to
    handle the mesh.
•   We have been able to decompose meshes with up to 500 000 000 elements, but we used a
    computing node with 512 gigs of memory.
•   For example, in a computing node with 16 gigs of memory, it is not possible to decompose a
    mesh with 30 000 000. You will need to use a computing node with at least 32 gigs of memory.
•   Same applies for the utility reconstructPar.
                                                                                                509
                                Running in parallel
                                Do all utilities run in parallel?
•   At this point, you might be wondering if all solvers/utilities run in parallel.
•   To know what solvers/utilities do not run in parallel, in the terminal type:
     •   $> find $WM_PROJECT_DIR -type f | xargs grep –sl ‘noParallel’
•   Paradoxically, the utilities used to decompose the domain and reconstruct the domain do not
    run in parallel.
•   Another important utility that does not run in parallel is blockMesh. So to generate big meshes
    with blockMesh you need to use a big fat computing node.
•   Another important utility that does not run in parallel by default is paraFoam.
•   To compile paraFoam with MPI support, in the file makeParaView (located in the directory
    $WM_THIRD_PARTY_DIR), set the option withMPI to true,
           •   withMPI = true
•   While you are working with the file makeParaView, you might consider enabling Python
    support,
           •   withPYTHON = true
                                                                                                  510
                                  Running in parallel
                                                  Exercises
•   Choose any tutorial or design your own case and do a scalability test. Scale your case with two different
    meshes (a coarse and a fine mesh).
•   Run the same case using different partitioning methods. Which method scales better? Do you get the same
    results?
•   Do you think that the best partitioning method is problem dependent?
•   Compare the wall time of a test case using the maximum number of cores and the maximum number of virtual
    cores. Which scenario is faster and why?
•   Run a parallel case without using the –parallel option. Does it run? Is it faster of slower? How many
    outputs do you see on the screen?
•   Do you get any speed-up by using renumberMesh?
•   What applications do not run in parallel?
                                                                                                                511
             Module 5
The postprocess utility – Sampling – Probing
     – On-the-fly postprocessing – Field
       manipulation – Data conversion
                                           512
                     Roadmap
                                                         513
       On-the-fly postprocessing – functionObjects
                                                                                           514
        On-the-fly postprocessing – functionObjects
•   In the directory $FOAM_SRC/functionObjects you will find the source code for the
    functionObjects.
•   There are many functionObjects, and according to what they do, they are located in different
    sub-directories, namely, field, forces, lagrangian, solvers, and utilities. Just to
    name a few functionObjects:
            •   courantNo                           •   forceCoeffs
            •   div                                 •   forces
            •   fieldAverage                        •   icoUncoupledKinematicCloud
            •   fieldMinMax                         •   scalarTransport
            •   grad                                •   codedFunctionObject
            •   MachNo                              •   residuals
            •   Q                                   •   systemCall
            •   vorticity                           •   timeActivatedFileUpdate
            •   yPlus                               •   writeObjects
    //   ...
    //   functionObject                                     Keywords and sub-dictionaries
    //   keywords and sub-dictionaries                      specific to the functionObject
    //   ...
                                                                                             516
       On-the-fly postprocessing – functionObjects
•   There are many functionObjects implemented in OpenFOAM®, and sometimes is
    not very straightforward how to use a specific functionObject.
•   Also, functionObjects can have many options and some limitations.
•   Our best advice is to read the doxygen documentation or the source code to learn
    how to use functionObjects.
•   Remember, the source code of the functionObjects is located in the directory:
         $WM_PROJECT_DIR/src/postProcessing/functionObjects
• The source code of the sampling and co-processing utilities is located in the directory:
         $WM_PROJECT_DIR/src/sampling
• The source code of the database entries required for the functionObjects is located
  in the directory:
         $FOAM_SRC/OpenFOAM/db/functionObjects
$PTOFC/101postprocessing/MDA_30P30N
•   In the case directory, you will find the README.FIRST file. In this file, you will find the general instructions of
    how to run the case. In this file, you might also find some additional comments.
•   You will also find a few additional files (or scripts) with the extension .sh, namely, run_all.sh,
    run_mesh.sh, run_sampling.sh, run_solver.sh, and so on. These files can be used to run the case
    automatically by typing in the terminal, for example, sh run_solver.
•   We highly recommend you to open the README.FIRST file and type the commands in the terminal, in this
    way, you will get used with the command line interface and OpenFOAM® commands.
•   If you are already comfortable with OpenFOAM®, use the automatic scripts to run the cases.
                                                                                                                      518
On-the-fly postprocessing – functionObjects
  At the end of the day, you should get something like this
cd cl
•   Let us run this case using the automatic scripts distributed with the tutorial. In the
    terminal type:
1. $> sh run_all.sh
•   After the simulation is finish, you will find the decomposed directories (processor0,
    processor1, processor2 and processor3), the postProcessing directory,
    and the 2000 directory. The solution, and output of the functionObjects, is saved in
    these directories.
•   Remember, to visualize the decomposed solution you will need to launch paraFoam
    as follows,
• Do not erase the solution as we are going to use it in the next section.
                                                                                             522
          On-the-fly postprocessing – functionObjects
                                          The controlDict dictionary
                                                           • Let us take a look at the bottom of the controlDict
51    functions                                              dictionary file. In this dictionary is where we define all
52    {
                                                             functionObjects.
          name_of_the_functionObject_dictionary
          {                                                • Within this dictionary, functionObjects are defined in
          }
              Sub-dictionary with functionObject entries
                                                             the sub-dictionary functions, i.e.,
70            //// Name of fields                                        Name of the velocity and pressure fields. If you use
71            pName p;
72            Uname U;                                                   different fields, e.g., pMean and Umean, they need to be
                                                                         computed before this functionObject
74            //only for incompressible flows                            Reference density value. It only needs to be defined for
75            rho rhoInf;
76            rhoInf 1.0;
                                                                         incompressible flows. For compressible flows, the
                                                                         computed density is used instead (you will need to define
                                                                         a dummy value, though)
78            //// Centre of rotation
79            CofR (0 0 0);                                              Reference center of rotation to compute moments
80    }
                                                                  Note:
211   }                                                           • The source code of this functionObject is located in the directory
                                                                    $FOAM_SRC/functionObjects/forces/forces
                                                                  • Use the banana method to know all the options available for each entry.   525
          On-the-fly postprocessing – functionObjects
                                             The controlDict dictionary
                                                                  •   Let us study now the functionObject used to
51    functions
52    {                                functionObject                 compute the force coefficients.
86    forceCoeffs_object
                                       identifier (user given)
87    {
88            type forceCoeffs;
89            functionObjectLibs ("libforces.so");
90
91            enabled true;
92                                                                     • This functionObject computes the force coefficients.
93            patches ("wall_slat" "wall_airfoil" "wall_flap");
94
                                                                       • These entries are similar to those of the force
95            pName p;                                                   functionObject
96            Uname U;
97
99            rho rhoInf;
100           rhoInf 1.0;
101
                                                                       This option will output the values to a text file located in the
103           log true;                                                directory postProcessing/forceCoeffs_object
104
105           CofR (0.0 0 0);
106                                                                    Reference center of rotation to compute moments
107           pitchAxis (0 0 1);
108           magUInf 1.0;
109           lRef 1;                                                  Reference values used to compute coefficients
110           Aref 1;
111
115           writeControl    timeStep;
116           writeInterval   1;                                       Controls for saving frequency
117
119           liftDir       (0 1 0);
120           dragDir       (1 0 0);                                   Reference axes to compute the lift and drag coefficients.
121
125   }
211 }
                                                                                                                                     526
          On-the-fly postprocessing – functionObjects
                                             The controlDict dictionary
                                                                  •   Let us study now the functionObject used to
51    functions
52    {                                functionObject                 compute the force coefficients.
86    forceCoeffs_object
                                       identifier (user given)
87    {
88            type forceCoeffs;
89            functionObjectLibs ("libforces.so");
90
91            enabled true;
92
93            patches ("wall_slat" "wall_airfoil" "wall_flap");
94
95            pName p;
96            Uname U;
97
99            rho rhoInf;
100           rhoInf 1.0;
101
103           log true;
104
105           CofR (0.0 0 0);
106
107           pitchAxis (0 0 1);
108           magUInf 1.0;
109           lRef 1;
110           Aref 1;
111
115           writeControl    timeStep;
116           writeInterval   1;
117                                                                    • Reference axes to compute the lift and drag coefficients.
119           liftDir       (0 1 0);
120           dragDir       (1 0 0);                                   • Remember, lift and drag are perpendicular and parallel
121
125   }                                                                  to the incoming flow, respectively.
24   probes_online
                                                                  • probes functionObject
25   {
26           type             probes;                                   • This functionObject is used to probe field data at the
27           functionObjectLibs ("libfieldFunctionObjects.so");           given locations.
28           enabled          true;
29           writeControl timeStep;                                     • In this case, we are sampling the fields U and p (lines 35-
30           writeInterval 1;
31                                                                        39)
32          probeLocations
33          (                                                           • The output of this functionObject is saved in ascii format
34                  (1 0    0)                                            in the files p and U located in the directory
35                  (2 0    0)
36                  (2 0.25        0)
                                                                              postProcessing/probes_online/0
37                  (2 -0.25       0)
38          );
39                                                                      • Remember, the name of the directory where the output
40          fields                                                        data is saved is the same as the name of the
41          (
42                   U
                                                                          functionObject (line 19).
43                   p
44          );
45
46   }                                                            • vorticity functionObject
52   vorticity                                                          • This functionObject is used to compute the vorticity field.
53   {
54           type vorticity;                                            • The output of this functionObject is saved in the solution
55           functionObjectLibs ("libfieldFunctionObjects.so");
56           enabled         true;
                                                                          directories (1, 2, 3, and so on). You can visualize this
57           log             true;                                        output using paraview/paraFoam.
58           writeControl    outputTime;
59   }
                                                                                                                                   530
        On-the-fly postprocessing – functionObjects
                            Final remarks on functionObjects
•   A functionObject that is very useful, but we did not use in this case:
                    inlet_massflow
                    {
                         type                     surfaceRegion;
                         functionObjectLibs ("libfieldFunctionObjects.so");
                         writeControl   timeStep;
                         writesInterval 1;
                         log             true;
                                                         Compute functionObject in a boundary patch
                         writeFields     false;
                         regionType      patch;
                         name            inlet;
                         operation       sum;
                                                         Compute functionObject in this boundary patch
                         fields (phi);
                    }
•   This functionObject is used to computed the mass flow across a boundary patch.
•   Remember, the method is conservative so what is going in, is going out (unless you have
    source terms).
•   So if you want to measure the mass imbalance, setup this function object for each boundary
    patch where you have flow entering or going out of the domain.
                                                                                                         531
       On-the-fly postprocessing – functionObjects
                         Final remarks on functionObjects
                                                                                           532
         On-the-fly postprocessing – functionObjects
                         Running functionObjects a-posteriori
•   Sometimes it can happen that you forget to use a functionObject or you want to execute a
    functionObject a-posteriori (when the simulation is over).
•   The solution to this problem is to use the solver with the option -postProcess. This will only
    compute the new functionObject, it will not rerun the simulation.
•   For instance, let us say that you forgot to use a given functionObject. Open the dictionary
    controlDict, add the new functionObject, and type in the terminal,
     •   $> name_of_the_solver -postProcess –dict dictionary_location
•   You also have the option of adding the new functionObject in an external file. If you chose this
    option, do not forget to add the functionOption within the function sub-dictionary block:
             function
             {
                  //functionObject definitions here
             };
•   By proceeding in this way you do not need to rerun the simulation, you just compute the new
    functionObject.
                                                                                                  533
            On-the-fly postprocessing – functionObjects
                            Running functionObjects a-posteriori
•        In the directory system, you will find the following functionObject external
         dictionaries: externalFunctionObject
•        To run this functionObject a-posteriori, type in the terminal:
                                                                                                                 535
                     Roadmap
                                                         536
              Sampling with the postProcess utility
•   OpenFOAM® provides the postProcess utility to sample field data for plotting.
•   The sampling parameters are specified in a dictionary located in the case system
    directory.
•   You can give any name to the input dictionary, hereafter we are going to name them
    sampleDict (to sample along a line) and probesDict (to sample in a set of
    probes).
•   During the sampling, and inside the case directory, a new directory named
    postProcessing will be created. In this directory, the sampled values are stored in
    a sub-directory with the name of the input dictionary, in this case, sampleDict and
    probesDict.
•   This utility can sample points, lines, and surfaces.
•   Data can be written in a range of formats including well-known plotting packages
    such as: grace/xmgr, gnuplot and jPlot.
•   The sampling can be executed by running the utility postProcess in the case
    directory and according to the application syntax.
•   A final word, this utility does not do the sampling while the solver is running. It does
    the sampling after you finish the simulation.
                                                                                               537
              Sampling with the postProcess utility
•   To do sampling, we will use the solution from the previous case.
•   If you do not have the solution, follow the instructions given in the previous slides.
•   Hereafter, we will sample along a line and in a few probe locations, as illustrated in
    the figure below.
                                                                                             538
             Sampling with the postProcess utility
                                  Running the case
                                                                                          539
             Sampling with the postProcess utility
                 The sampleDict and probesDict dictionaries
•   These dictionaries are located in the directory system.
•   In this case, the sampleDict dictionary is used to sample along a line. This file
    contains several entries to be set according to the user needs. The following entries
    can be set,
           • The choice of the interpolationScheme.
           • The format of the line data output.
           • The format of the surface data output.
           • The fields to be sample.
           • The sub-dictionaries that controls each sampling operation.
           • In these sub-dictionaries you can set the name, type and geometrical
              information of the sampling operation.
•   In this case, the probesDict is used to sample in a set of points. This file contains
    several entries to be set according to the user needs. The following entries,
           • The fields to be sample.
           • Location of the probes.
•   The following functionObjects type can be used to do sampling: patchProbes,
    probes, sets, or surfaces.
                                                                                        540
                  Sampling with the postProcess utility
                                           The sampleDict dictionary
                                                      Note:
66   );
                                                      Use the banana method to know all the options available.                541
                  Sampling with the postProcess utility
                                           The sampleDict dictionary
48 }
66   );
                                                                                                                          542
                Sampling with the postProcess utility
                        The probesDict dictionary
20   (
21        p
22        U                        Fields to sample. No need to mention that they must exist.
23   );
27   probeLocations
28   (
29       (1.0   0 0)
30       (1.25 0 0)
31       (1.5 0 0)
32       (1.75 0 0)
33       (2.0   0 0)               Location of the points.
34       (2.0 -.25 0)
35       (2.0 -.5 0)
36       (2.0 .25 0)
37       (2.0 .5 0)
38   );
                                Note:
                                Use the banana method to know all the options available.        543
                Sampling with the postProcess utility
                        The probesDict dictionary
                                                                                                  544
             Sampling with the postProcess utility
             The output files – functionObject type sets or surfaces
Scalars
      #POINT_COORDINATES (X Y Z)           SCALAR_VALUE
      0   0   0.05                         13.310995
      0   0   0.1                          19.293817
      …
Vectors
      #POINT_COORDINATES (X Y Z)           VECTOR_COMPONENTS (X Y Z)
      0   0   0.05                         0   0   2.807395
      0   0   0.1                          0   0   2.826176
      …
                                                                       545
             Sampling with the postProcess utility
             The output files – functionObject type sets or surfaces
Scalars
      #AXIS_COORDINATE           SCALAR_VALUE
      0                          18.594038
      0.0015                     18.249091
      …
Vectors
      #AXIS_COORDINATE           VECTOR_COMPONENTS (X Y Z)
      0                          0   0   1.6152966
      0.0015                     0   0   1.8067536
      …
                                                                       546
             Sampling with the postProcess utility
            The output files – functionObject type sets or surfaces
Scalars
      #POINT_COORDINATES (X Y Z)          SCALAR_VALUE
      0   0   0.05                        13.310995
      0   0   0.1                         19.293817
      …
Vectors
      #POINT_COORDINATES (X Y Z)          VECTOR_COMPONENTS (X Y Z)
      0   0   0.05                        0   0   2.807395
      0   0   0.1                         0   0   2.826176
      …
                                                                      547
              Sampling with the postProcess utility
                     The output files – functionObject type probes
Scalars
      # Probe 0 (0 0 0.025)
      # Probe 1 (0 0 0.05)
      # Probe 2 (0 0 0.075)
      # Probe 3 (0 0 0.1)
      #    Probe              0         1             2         3
      #    Time
           0                  0         0             0         0
           0.005              19.1928   16.9497       14.2011   11.7580
           0.01               16.6152   14.5294       12.1733   10.0789
           …
           …
           …
                                                                          548
              Sampling with the postProcess utility
                     The output files – functionObject type probes
Vectors
      # Probe 0 (0 0 0.025)
      # Probe 1 (0 0 0.05)
      # Probe 2 (0 0 0.075)
      # Probe 3 (0 0 0.1)
      #    Probe              0              1              2              3
      #    Time
           0                  (0 0 0)        (0 0 0)        (0 0 0)        (0 0 0)
           0.005              (0 0 2.1927)   (0 0 2.1927)   (0 0 2.1927)   (0 0 2.1927)
           0.01               (0 0 2.5334)   (0 0 2.5334)   (0 0 2.5334)   (0 0 2.5334)
           …
           …
           …
                                                                                          549
                 Sampling with the postProcess utility
                                                   Exercises
•   Where is located the source code of the utility postProcess?
•   Try to do the sampling in parallel? Does it run? What about the output file?
•   How many options are there available to do sampling in a line?
•   Do point, line, and surface sampling using paraFoam/ParaView and compare with the output of the
    postProcess utility. Do you get the same results?
•   Compute the descriptive statistics of each column of the output files using gnuplot. Be careful with the
    parentheses of the vector files.
    (Hint: you can use sed within gnuplot)
                                                                                                               550
                     Roadmap
                                                         551
                        Field manipulation
• Hereafter we are going to deal with field manipulation
• Field manipulation means modifying a field variable or deriving a new field
  variable using the primitive variables computed during the solution stage.
• We will do the post-processing using the command line interface (CLI), or
  non-GUI mode.
• The utility postProcess can be used as a single application, e.g.,
        • $> postProcess –func vorticity
• Running the solver with the option –postprocess will only execute the
  post-processing and it will let you access data available on the database for
  the particular solver (such as physical properties or turbulence model).
                                                                                552
                       Field manipulation
• To get a list of what can be computed using the postProcess utility, type in
  the terminal:
        • $> postProcess –list
• The utility postProcess can take many options. To get more information
  on how to use the utility, type in the terminal:
       • $> postProcess –help
        • $> simpleFoam -postProcess –help
• The options of the solver using the –postProcess flag are the same as the
  options of the utility postProcess.
• In the sub-directory $FOAM_UTILITIES/postProcessing/postProcess
  you will find the utility postProcess.
• In the directory $FOAM_SRC/functionObjects, you will find the source
  code of the objects that can be used to compute a new field.
                                                                             553
                                    Field manipulation
$PTOFC/101postprocessing/supersonic_wedge/
•   In the case directory, you will find the README.FIRST file. In this file, you will find the general instructions of
    how to run the case. In this file, you might also find some additional comments.
•   You will also find a few additional files (or scripts) with the extension .sh, namely, run_all.sh,
    run_mesh.sh, run_sampling.sh, run_solver.sh, and so on. These files can be used to run the case
    automatically by typing in the terminal, for example, sh run_solver.
•   We highly recommend you to open the README.FIRST file and type the commands in the terminal, in this
    way, you will get used with the command line interface and OpenFOAM® commands.
•   If you are already comfortable with OpenFOAM®, use the automatic scripts to run the cases.
                                                                                                                      554
                           Field manipulation
After computing the solution, we can compute derived fields (e.g., Mach number, density,
        Courant number, vorticity, and so on), using the primitive fields (U, p, T)
                 Mach number                                     Total pressure
                                                                                                      555
                               Field manipulation
                                  What are we going to do?
•   We will use this case to introduce the postProcess utility for field manipulation.
•   We will also show how to run the solver with the option -postProcess. This will let us do only
    the post-processing after the solution has been computed, and it will let us access the database
    of the solver.
•   To find the numerical solution we will use the solver rhoPimpleFoam.
•   rhoPimpleFoam is a transient solver for laminar or turbulent flow of compressible gas.
    1.    $> sh run_solver.sh
    2.    $> paraFoam
• Fell free to open the file run_solver.sh to know all the steps.
                                                                                                  556
                         Field manipulation
• After finding the solution, we can compute the new field variables using the
  primitive variables computed during the solution stage. In the terminal type:
                                                                                             558
                           Field manipulation
•   After finding the solution, we can compute new field variables using the primitive
    variables computed during the solution stage. In the terminal type:
•   We can also use the utility postProcess to compute the average and integral of a
    specified field over a patch. In the terminal type:
                                                                                                  560
                     Roadmap
                                                         561
                             Data conversion
• OpenFOAM® gives users a lot of flexibility when it comes to scientific visualization.
• You are not obliged to use OpenFOAM® visualization tools (paraFoam or paraview).
• You can convert the solution obtained with OpenFOAM® to many third-party formats
  by using OpenFOAM® data conversion utilities.
• If you are looking for a specific format and it is not supported, you can write your own
  conversion tool.
• In the directory $FOAM_UTILITIES/postProcessing/dataConversion, you will
  find the source code of the following data conversion utilities:
   • foamDataToFluent                         • foamToTecplot360
   • foamToEnsight                            • foamToTetDualMesh
   • foamToEnsightParts                       • foamToVTK
   • foamToGMV                                • smapToFoam
• To get more information on how to use a data conversion utility, you can read the
  source code or type in the terminal:
    • $> name_of_data_conversion_utility -help
                                                                                          562
                                     Data conversion
                                   ASCII ↔ Binary conversion
                                       •   Another utility that might come in handy, specially when dealing with
                                           large meshes is foamFormatConvert.
17
18
     application      icoFoam;         •   This utility converts the mesh and field variables into ascii or binary
19   startFrom        startTime;           format.
20
21   startTime        0;               •   In order to manually edit the boundary file and the field variables
22
23   stopAt           endTime;             dictionaries (initial and boundary conditions), they must be in ascii
24
25   endTime          50;                  format.
26
27   deltaT           0.01;            •   After editing these files, we can convert them into binary format.
28
29
30
     writeControl     runTime;
                                       •   Working in binary format can significantly reduce data parsing and
31   writeInterval    1;                   dimension of the files (specially for large meshes).
32
33
34
     purgeWrite       0;
                                       •   The drawback is that the files are not human readable anymore.
35   writeFormat      binary;
36                                     •   To convert ascii files into binary files, just type in the terminal:
37   writePrecision   8;
38                                                 •   $> foamFormatConvert
39   writeCompression off;
40
41   timeFormat       general;         •   Remember you will need to set the keyword writeFormat to binary
42
43   timePrecision    6;
                                           in the controlDict dictionary.
44
45   runTimeModifiable true;           •   In the same way, if you want to convert from binary to ascii, set the
                                           keyword writeFormat to ascii in the controlDict dictionary and
                                           type in the terminal:
                                                   •   $> foamFormatConvert
                                                                                                                  563
      Module 6
Finite volume method overview
                                564
                    Roadmap
                                                  565
  Finite Volume Method: A Crash introduction
• This a brief introduction to the FVM to illustrate some basic concepts.
• There is much more under the hood.
• We will use the general transport equation as the starting point to explain the FVM,
• Starting from this equation, we can write down the Navier-Stokes equations (NSE).
• So everything we are going to address also applies to the NSE or any set of
  equations that can be derived form the general transport equation.
                                                                                         566
  Finite Volume Method: A Crash introduction
• This a brief introduction to the FVM to illustrate some basic concepts.
• There is much more under the hood.
• We will use the general transport equation as the starting point to explain the FVM,
                                  Problem statement
• Find the approximate solution to the general transport equation for the transported
  quantity     in a given domain, with given boundary conditions (BC) and initial
  conditions (IC).
• It is an initial boundary value problem (IBVP).
• This is a second order equation. Therefore, for good accuracy, it is necessary that
  the order of the discretization is equal or higher than the order of the equation that is
  being discretized (in space and time).
                                                                                          567
  Finite Volume Method: A Crash introduction
• Let us use the general transport equation as the starting point to explain the FVM,
 • Hereafter we are going to assume that the discretization practice is at least second
   order accurate in space and time.
 • As consequence of the previous requirement, all dependent variables are assumed
   to vary linearly around a point P in space and instant t in time,
Profile assumptions using Taylor expansions around point P (in space) and point t (in time)
                                                                                                       568
    Finite Volume Method: A Crash introduction
     Domain discretization – Mesh information and variable arrangement
•   Domain discretization (or mesh generation), consist in dividing the solution domain into a finite
    number of arbitrary control volumes or cells, such as the one illustrated below.
•   Inside each control volume the solution is sought.
•   The control volumes can be of any shape (e.g., tetrahedrons, hexes, prisms, pyramids,
    dodecahedrons, and so on). The only requirement is that the faces that made up the control
    volume need to be planar.
•   We also know which control volumes are internal and which control volumes lie on the
    boundaries.
                                                                                                        569
    Finite Volume Method: A Crash introduction
     Domain discretization – Mesh information and variable arrangement
•   In the control volume illustrated, the centroid P and face center f are known.
•   We also assume that the values of all variables are computed and stored in the centroid of the
    control volume Vp and that they are represented by a piecewise constant profile (the mean
    value),
                                                                                                     570
    Finite Volume Method: A Crash introduction
         Domain discretization – Mesh information and variable arrangement
•       Putting all together, it is a lot geometrical information that we need to track.
•       A lot of overhead goes into the data book-keeping.
•       At the end of the day, the FVM simply consist in conservation of the transported quantities and
        interpolating information from cell centers to face centers.
    Summary:
    •     The control volume      has a volume V and is constructed
          around point P, which is the centroid of the control volume.
          Therefore the notation     .
    •     The vector from the centroid P of     to the centroid N of the
          neighboring control volume       is named d.
    •     We also know all neighbors      of the control volume
    •     The control volume faces are labeled f, which also denotes the
          face center.
    •     The location where the vector d intersects a face is    .
    •     The face area vector        point outwards from the control
          volume, is located at the face centroid, is normal to the face and
          has a magnitude equal to the area of the face.
    •     The vector from the centroid P to the face center f is named Pf.
                                                                                                          571
    Finite Volume Method: A Crash introduction
                      Gauss theorem and face fluxes computation
•   Let us recall the Gauss or Divergence theorem,
                                                                                                 572
    Finite Volume Method: A Crash introduction
                    Gauss theorem and face fluxes computation
•   Let us use the Gauss theorem to convert the volume integrals into surface integrals,
•   At this point the problem reduces to interpolating somehow the cell centered values (known
    quantities) to the face centers.
•   That is, we need to compute the gradient terms, source terms, and convective and diffusive
    fluxes across the faces.                                                                     573
     Finite Volume Method: A Crash introduction
                         Gauss theorem and face fluxes computation
•    Integrating in space each term of the general transport equation and by using Gauss theorem,
     yields to the following discrete equations for each term
Convective term:
        By using Gauss theorem we convert volume   where we have approximated the integrant by means of
        integrals into surface integrals           the mid point rule, which is second order accurate
Gauss theorem:
                                                                                                          574
     Finite Volume Method: A Crash introduction
                         Gauss theorem and face fluxes computation
•    Integrating in space each term of the general transport equation and by using Gauss theorem,
     yields to the following discrete equations for each term
Diffusive term:
        By using Gauss theorem we convert volume    where we have approximated the integrant by means of
        integrals into surface integrals            the mid point rule, which is second order accurate
Gauss theorem:
                                                                                                           575
     Finite Volume Method: A Crash introduction
                     Gauss theorem and face fluxes computation
•    Integrating in space each term of the general transport equation and by using Gauss theorem,
     yields to the following discrete equations for each term
Gradient term:
                       where we have approximated the centroid gradients by using the Gauss theorem.
                       This method is second order accurate and is known as Gauss cell-based.
Gauss theorem:
                                                                                Note:
                                                                                • There are more methods for gradients
                                                                                  computation, e.g., least squares, node-
                                                                                  based reconstruction, and so on.
                                                                                • As there is some algebra involved, we
                                                                                  do not provide the demonstration.
                                                                                                                       576
     Finite Volume Method: A Crash introduction
                         Gauss theorem and face fluxes computation
•    Integrating in space each term of the general transport equation and by using Gauss theorem,
     yields to the following discrete equations for each term
Source term:
            This approximation is exact if     is either constant or varies linearly within the control volume; otherwise is
            second order accurate.
            Sc is the constant part of the source term and Sp is the non-linear part
Gauss theorem:
                                                                                                                               577
        Finite Volume Method: A Crash introduction
                         Gauss theorem and face fluxes computation
•       Using the previous equations to evaluate the general transport equation over all the control
        volumes, we obtain the following semi-discrete equation
• And recall that all variables are computed and stored at the centroid of the control volumes.
    •    The face values appearing in the convective and diffusive fluxes have to be computed by
         some form of interpolation from the centroid values of the control volumes at both sides of
         face f.
                                                                                                           578
    Finite Volume Method: A Crash introduction
                          Interpolation of the convective fluxes
•   By looking the figure below, the face values appearing in the convective flux can be computed
    as follows,
•   This type of interpolation scheme is known as linear interpolation or central differencing and it is
    second order accurate.
•   However, it may generate oscillatory solutions (unbounded solutions).
                                                                                                      579
    Finite Volume Method: A Crash introduction
                          Interpolation of the convective fluxes
•   By looking the figure below, the face values appearing in the convective flux can be computed
    as follows,
•   This type of interpolation scheme is known as upwind differencing and it is first order accurate.
•   This scheme is bounded (non-oscillatory) and diffusive.
                                                                                                        580
    Finite Volume Method: A Crash introduction
                          Interpolation of the convective fluxes
•   By looking the figure below, the face values appearing in the convective flux can be computed
    as follows,
•   This type of interpolation scheme is known as second order upwind differencing (SOU), linear
    upwind differencing (LUD) or Beam-Warming (BW), and it is second order accurate.
•   For highly convective flows or in the presence of strong gradients, this scheme is oscillatory
    (unbounded).
                                                                                                     581
    Finite Volume Method: A Crash introduction
                          Interpolation of the convective fluxes
•   To prevent oscillations in the SOU, we add a gradient or slope limiter function       .
•   When the limiter detects strong gradients or changes in slope, it switches locally to low
    resolution (upwind).
•   The concept of the limiter function       is based on monitoring the ratio of successive
    gradients, e.g.,
                                                                                                582
   Finite Volume Method: A Crash introduction
                Interpolation of the convective fluxes – TVD schemes
                                                                                      583
    Finite Volume Method: A Crash introduction
               Interpolation of the convective fluxes – TVD schemes
•   Let us see how the upwind, linear upwind, linear, and Minmod TVD schemes behave in a
    numerical schemes killer test case:
     •   The oblique double step profile in a uniform vector field (pure convection).
•   Even if this problem seems to be easy, from the numerical point of view is difficult to resolve due
    to the strong discontinuities.
•   This problem has an exact solution.
                                                                                                     584
    Finite Volume Method: A Crash introduction
                  Interpolation of the convective fluxes – TVD schemes
•   Qualitative comparison of the upwind, linear upwind, linear, and Minmod TVD schemes
          Upwind – 1st order                 Linear – 2nd order             Linear Upwind – 2nd order
    Very bounded but too Diffusive    Very accurate but too oscillatory      Bounded and accurate
    SuperBee – TVD high resolution     Minmod – TVD high resolution       vanLeer – TVD high resolution
            Compressive                         Diffusive                            Smooth
                                                                                                          585
    Finite Volume Method: A Crash introduction
              Interpolation of the convective fluxes – TVD schemes
•   Quantitative comparison of the upwind, linear upwind, linear, and Minmod TVD schemes
                                                                                           586
    Finite Volume Method: A Crash introduction
         Interpolation of the convective fluxes – Unstructured meshes
•   In the previous explanation, we assumed a line structure (figure A). That is, the cell centers PP,
    P, and N are all aligned.
•   In unstructured meshes (which are often used in industrial cases), most of the times the cell
    center PP is not aligned with the vector connecting cells P and N (figure B). Therefore,
    extending the previous formulations to these meshes is not very straightforward.
•   Higher-order schemes for unstructured meshes are an area of active research, and new ideas
    continue to emerge.
                                                                                                     587
    Finite Volume Method: A Crash introduction
         Interpolation of the convective fluxes – Unstructured meshes
•   A simple way around this problem is to redefine
    higher-order schemes in terms of gradients at the
    control volume P.
•   For example, using the gradient of the cells, we can
    compute the face values as follows,
Upwind →
Central difference →
•   Notice that in this new formulation the cell PP does not appear anymore.
•   The problem now turns in the accurate evaluation of the gradients at the cell and face centers.
•   For example, the gradients at the cell centers can be computed using the Gauss method, and
    then interpolated to the face centers.
•   At this point, we are only missing the reconstruction of the cell center gradients at the face
    centers, this is explained latter.                                                               588
    Finite Volume Method: A Crash introduction
           Interpolation of the convective fluxes – Unstructured meshes
•   In unstructured meshes, as often the value of the node PP (of NN) is not available or
    straightforward to compute, the ratio of successive gradients r can be computed as follows [1],
                                                                             U → Upwind
                                                                             D → Downwind
Reference:
[1] Darwish, M. S., Moukalled, F., “TVD schemes for unstructured grids”                               589
    Finite Volume Method: A Crash introduction
                         Gradients computation at cell centers
•   There are many methods for the computation of the cell centered gradients, e.g., least squares,
    Gauss cell-based, Gauss node-based, and so on.
•   Using the Gauss cell-based method, the cell centered gradients can be computed as follows,
•   This approximation is second order accurate given that the mesh quality is acceptable, and the
    volume of the cell is finite.
•   In general, the least squares method tends to be more accurate.
                                                                                                 590
    Finite Volume Method: A Crash introduction
                       Gradients reconstruction at face centers
•   Face gradients       arise from the discretization process of the convective and diffusive terms.
•   One way to reconstruct the face gradient             , is by using weighted interpolation of the cell
    centered quantities      and       .
•   Mesh non-orthogonality and skewness introduce errors when approximating the face gradients,
    so corrections need to be added.
•   This is an iterative process, where we compute successively better approximations to the
    gradients starting from an initial approximation.
where
Face gradient
                                                                                                            591
    Finite Volume Method: A Crash introduction
                Interpolation of diffusive fluxes in an orthogonal mesh
•   By looking the figure below, the face values        •   By looking the figure below, the face values
    appearing in the diffusive flux in an orthogonal        appearing in the diffusive flux in a non-orthogonal
    mesh can be computed as follows,                        mesh (20°) can be computed as follows,
•   This is a central difference approximation of the   •   This type of approximation is second order accurate
    first order derivative. This type of                    but involves a larger truncation error. It also uses a
    approximation is second order accurate.                 larger numerical stencil, which make it less stable.
•   Remember, the non-orthogonal angle is the angle between the vector S and the vector d
                                                                                                                  592
    Finite Volume Method: A Crash introduction
             Correction of diffusive fluxes in a non-orthogonal mesh
•   By looking the figures below, the face values appearing in the diffusive flux in a non-orthogonal
    mesh (      ) can be computed as follows.
•   Using the over-relaxed approach, the diffusive fluxes can be corrected as follow,
Over-relaxed approach
                                                                                                    593
    Finite Volume Method: A Crash introduction
                                    Mesh induced errors
•   In order to maintain second order accuracy, and to avoid unboundedness, we need to correct
    non-orthogonality and skewness errors.
•   The ideal case is to have an orthogonal and non skew mesh, but this is the exception rather
    than the rule.
Orthogonal and non skew mesh Non-orthogonal and non skew mesh
    •   After spatial discretization, we can proceed with the temporal discretization. By proceeding
        in this way we are using the Method of Lines (MOL).
    •   The main advantage of the MOL method, is that it allows us to select numerical
        approximations of different accuracy for the spatial and temporal terms. Each term can be
        treated differently to yield to different accuracies.
                                                                                                         595
    Finite Volume Method: A Crash introduction
                                    Temporal discretization
•   Now, we evaluate in time the semi-discrete general transport equation
•   At this stage, we can use any time discretization scheme, e.g., Crank-Nicolson, euler implicit,
    forward euler, backward differencing, adams-bashforth, adams-moulton.
•   It should be noted that the order of the temporal discretization of the transient term does not
    need to be the same as the order of the discretization of the spatial terms.
•   Each term can be treated differently to yield different accuracies. As long as the individual terms
    are at least second order accurate, the overall accuracy will also be second order.
                                                                                                      596
    Finite Volume Method: A Crash introduction
                                   Linear system solution
•   After spatial and temporal discretization and by using equation
    in every control volume      of the domain, a system of linear algebraic equations for the
    transported quantity    is assembled,
•   This system can be solved by using any iterative or direct method.                           597
  Finite Volume Method: A Crash introduction
                             So, what does OpenFOAM® do?
• It simply discretize in space and time the governing equations in arbitrary polyhedral control
  volumes over the whole domain.
• Assembling in this way a large set of linear discrete algebraic equations (DAE), and then it solves
  this system of DAE to find the solution of the transported quantities.
• Therefore, we need to give to OpenFOAM® the following information:
     • Discretization of the solution domain or the mesh.
               • This information is contained in the directory constant/polyMesh
     • Boundary conditions and initials conditions.
               • This information is contained in the directory 0
     • Physical properties such as density, gravity, diffusion coefficient, viscosity, etc.
               • This information is contained in the directory constant
     • Physics involve, such as turbulence modeling, mass transfer, source terms, dynamic
       meshes, multiphase models, combustion models, etc.
               • This information is contained in the directories constant and/or system
                                                                                                   598
  Finite Volume Method: A Crash introduction
                           So, what does OpenFOAM® do?
• Therefore, we need to give to OpenFOAM® the following information:
    • How to discretize in space each term of the governing equations (diffusive, convective,
      gradient and source terms).
              • This information is set in the system/fvSchemes dictionary.
    • How to discretize in time the obtained semi-discrete governing equations.
              • This information is set in the system/fvSchemes dictionary.
    • How to solve the linear system of discrete algebraic equations (crunch numbers).
              • This information is set in the system/fvSolution dictionary.
    • Set runtime parameters and general instructions on how to run the case (such as time step,
      maximum CFL number, solution saving frequency, and so on).
              • This information is set in the system/controlDict dictionary.
    • Additionally, we may set sampling and monitors for post-processing (functionObjects).
              • This information is set in the system/fvSchemes dictionary or in the specific
                sampling dictionaries located in the directory system/
                                                                                                599
Finite Volume Method: A Crash introduction
    Where do we set all the discretization schemes in OpenFOAM®?
ddtSchemes                                • The fvSchemes dictionary contains the information related to
{                                           the discretization schemes for the different terms appearing in
     default      backward;
}
                                            the governing equations.
gradSchemes
                                          • The discretization schemes can be chosen in a term-by-term
{                                           basis.
     default      Gauss linear;
     grad(p)      Gauss linear;           • The keyword ddtSchemes refers to the time discretization.
}
                                          • The keyword gradSchemes refers to the gradient term
divSchemes                                  discretization.
{
     default      none;                   • The keyword divSchemes refers to the convective term
     div(phi,U)    Gauss linear;            discretization.
}
                                          • The keyword laplacianSchemes refers to the Laplacian term
laplacianSchemes
{
                                            discretization.
     default   Gauss linear orthogonal;   • The keyword interpolationSchemes refers to the method used
}
                                            to interpolate values from cell centers to face centers. It is
interpolationSchemes                        unlikely that you will need to use something different from
{                                           linear.
      default    linear;
}                                         • The keyword snGradSchemes refers to the discretization of
snGradSchemes
                                            the surface normal gradients evaluated at the faces.
{
    default   orthogonal;
                                          • Remember, if you want to know the options available for each
}                                           keyword you can use the banana method.
                                                                                                          600
    Finite Volume Method: A Crash introduction
                                 Time discretization schemes
•   There are many time discretization schemes available in OpenFOAM®.
•   You will find the source code in the following directory:
      •   $WM_PROJECT_DIR/src/finiteVolume/finiteVolume/ddtSchemes
•   These are the time discretization schemes that you will use most of the times:
           •   steadyState: for steady state simulations (implicit/explicit).
           •   Euler: time dependent first order (implicit/explicit), bounded.
           •   backward: time dependent second order (implicit), bounded/unbounded.
           •   CrankNicolson: time dependent second order (implicit), bounded/unbounded.
                                                                                                     601
    Finite Volume Method: A Crash introduction
                                Time discretization schemes
•   The Crank-Nicolson method as it is implemented in OpenFOAM®, uses a blending factor.
                          ddtSchemes
                          {
                              default       CrankNicolson        ;
                          }
•   Setting    to 0 is equivalent to running a pure Euler scheme (robust but first order accurate).
•   By setting the blending factor equal to 1 you use a pure Crank-Nicolson (accurate but
    oscillatory, formally second order accurate).
•   If you set the blending factor to 0.5, you get something in between first order accuracy and
    second order accuracy, or in other words, you get the best of both worlds.
•   A blending factor of 0.7-0.9 is safe to use for most applications (stable and accurate).
                                                                                                      602
    Finite Volume Method: A Crash introduction
                        Convective terms discretization schemes
•   There are many convective terms discretization schemes available in OpenFOAM® (more than
    50 last time we checked).
•   You will find the source code in the following directory:
      •   $WM_PROJECT_DIR/src/finiteVolume/interpolation/surfaceInterpolation
•   These are the convective discretization schemes that you will use most of the times:
           •   upwind: first order accurate.
           •   linearUpwind: second order accurate, bounded.
           •   linear: second order accurate, unbounded.
           •   A good TVD scheme (vanLeer or Minmod): TVD, second order accurate, bounded.
           •   limitedLinear: second order accurate, unbounded, but more stable than pure linear.
               Recommended for LES simulations (kind of similar to the Fromm method).
           •   LUST: blended 75% linear and 25% linearUpwind scheme
               gradSchemes
               {
                    grad(U)        cellMDLimited Gauss linear 1.0;
               }
               divSchemes
               {
                   div(phi,U)      Gauss linearUpwind             grad(U);
               }
                                                                                          604
    Finite Volume Method: A Crash introduction
                         Gradient terms discretization schemes
•   There are many gradient discretization schemes available in OpenFOAM®.
•   You will find the source code in the following directory:
      •   $WM_PROJECT_DIR/src/finiteVolume/finiteVolume/gradSchemes
•   These are the gradient discretization schemes that you will use most of the times:
           •   Gauss linear (cell-based method)
           •   Gauss pointLinear (node-based method; more accurate than the cell-based method)
           •   leastSquares
•   To avoid overshoots or undershoots when computing the gradients, you can use gradient
    limiters.
•   Gradient limiters increase the stability of the method but add diffusion due to clipping.
•   You will find the source code in the following directory:
      •   $WM_PROJECT_DIR/src/finiteVolume/finiteVolume/gradSchemes/limitedGradSchemes
•   These are the most important gradient limiter schemes available in OpenFOAM®:
      •   cellLimited, cellMDLimited, faceLimited, faceMDLimited
•   All of the gradient discretization schemes are at least second order accurate.
                                                                                                605
    Finite Volume Method: A Crash introduction
                            Gradient terms discretization schemes
•   These are the gradient limiter schemes available in OpenFOAM®:
                 gradSchemes
                 {
                     default        cellLimited          Gauss linear         ;
                 }
•   Setting   to 0 is equivalent to turning off the gradient limiter. You gain accuracy but the solution
    might become unbounded.
•   By setting the blending factor equal to 1 the limiter is set to be very aggressive (kind of saying
    that it is always on). You gain stability but you give up accuracy (due to gradient clipping).
•   If you set the blending factor to 0.5, you get the best of both worlds.
•   You can use limiters with all gradient discretization schemes.
                                                                                                         607
    Finite Volume Method: A Crash introduction
                          Laplacian terms discretization schemes
•   There are many Laplacian terms discretization schemes available in OpenFOAM®.
•   You will find the source code in the following directory:
      •   $WM_PROJECT_DIR/src/finiteVolume/finiteVolume/snGradSchemes
•   These are the Laplacian terms discretization schemes that you will
    use most of the times:
      •   orthogonal: mainly limited for hexahedral meshes with no
          grading (a perfect mesh). Second order accurate, bounded
          on perfect meshes, without non-orthogonal corrections.
      •   corrected: for meshes with grading and non-orthogonality.                Can be computed using the over-relaxed approach
                                                     Only option
                   laplacianSchemes
                   {
                        default  Gauss                 linear            limited          ;
                   }
                                                                   Interpolation method of the diffusion coefficient
•   Setting      to 1 is equivalent to using the corrected method. You gain accuracy, but the solution might
    become unbounded.
•   By setting the blending factor equal to 0 is equivalent to using the uncorrected method. You give up accuracy
    but gain stability.
•   If you set the blending factor to 0.5, you get the best of both worlds. In this case, the non-orthogonal
    contribution does not exceed the orthogonal part. You give up accuracy but gain stability.
•   For meshes with non-orthogonality less than 70, you can set the blending factor to 1.
•   For meshes with non-orthogonality between 70 and 85, you can set the blending factor to 0.5
•   For meshes with non-orthogonality more than 85, it is better to get a better mesh. But if you want to use that
    mesh, you can set the blending factor to 0.333-0.5, and increase the number of non-orthogonal corrections.
•   If you are doing LES or DES simulations, use a blending factor of 1 (this means that you need good meshes).   609
    Finite Volume Method: A Crash introduction
                         Laplacian terms discretization schemes
•   Just to make it clear, the blending factor        is used to avoid the non-orthogonal contribution
    exceeding the orthogonal part.
•   That is, non-orthogonal contribution ≤ orthogonal contribution.
The blending factor works as a limiter acting on this term (non-orthogonal contribution)
•   In meshes with large non-orthogonality, the explicit term can lead to unboundedness and
    eventually divergence.
•   This limiting is local, similar to the treatment done for the connective terms when using slope
    limiters and TVD schemes.
•   The explicit contribution is added to the RHS of the linear system (source term), so if this term
    becomes too large it will lead to convergence problems.
•   It becomes harder to guarantee diagonal dominance of the matrix of coefficient.
                                                                                                                          610
    Finite Volume Method: A Crash introduction
                        Laplacian terms discretization schemes
•   The surface normal gradients terms usually use the same method as the one chosen for the
    Laplacian terms.
•   For instance, if you are using the limited 1 method for the Laplacian terms, you can use the
    same method for snGradSchemes:
                 laplacianSchemes
                 {
                      default              Gauss linear        limited 1;
                 }
                 snGradSchemes
                 {
                     default               limited 1;
                 }
                                                                                                   611
 Finite Volume Method: A Crash introduction
                                          What method should I use?
ddtSchemes                                                  • This setup is recommended for most of
{
      default        CrankNicolson 0;
                                                              the cases.
}
gradSchemes                                                 • It is equivalent to the default method you will find in
{                                                             commercial solvers.
      default        cellLimited Gauss linear 0.5;
      grad(U)        cellLimited Gauss linear 1;            • In overall, this setup is second order accurate and
}
divSchemes
                                                              fully bounded.
{
      default                none;
                                                            • According to the quality of your mesh, you will need
      div(phi,U)             Gauss linearUpwindV grad(U);     to change the blending factor of the
      div(phi,omega)         Gauss linearUpwind default;      laplacianSchemes and snGradSchemes
      div(phi,k)             Gauss linearUpwind default;
                                                              keywords.
      div((nuEff*dev(T(grad(U))))) Gauss linear;
}
laplacianSchemes
                                                            • To keep temporal diffusion to a minimum, use a CFL
{                                                             number less than 2, and preferably below 1.
      default        Gauss linear limited 1;
}                                                           • If during the simulation the turbulence quantities
interpolationSchemes
{
                                                              become unbounded, you can safely change the
      default        linear;                                  discretization scheme to upwind. After all,
}
snGradSchemes
                                                              turbulence is diffusion.
{
      default        limited 1;                             • For gradient discretization the leastSquares
}                                                             method is more accurate. But we have found that it
                                                              is a little bit oscillatory in tetrahedral meshes.
                                                                                                                   612
 Finite Volume Method: A Crash introduction
                              A very accurate but oscillatory numerics
ddtSchemes                                          • If you are looking for more accuracy, you can use
{
     default        backward;
                                                      this method.
}
gradSchemes                                         • In overall, this setup is second order accurate but
{                                                     oscillatory.
     default        Gauss leastSquares;
}                                                   • Use this setup with LES simulations or laminar
divSchemes
{                                                     flows with no complex physics and meshes with
     default               none;                      overall good quality.
     div(phi,U)            Gauss linear;
     div(phi,omega)        Gauss limitedlinear 1;   • Use this method with good quality meshes.
     div(phi,k)            Gauss limitedLinear 1;
     div((nuEff*dev(T(grad(U))))) Gauss linear;     • According to the quality of your mesh, you will need
}
laplacianSchemes
                                                      to change the blending factor of the
{                                                     laplacianSchemes and snGradSchemes
      default      Gauss linear limited 1;            keywords.
}
interpolationSchemes
{
      default      linear;
}
snGradSchemes
{
      default      limited 1;
}
                                                                                                            613
 Finite Volume Method: A Crash introduction
                              A very stable but too diffusive numerics
ddtSchemes                                         • If you are looking for extra stability, you can use this
{
      default        Euler;
                                                     method.
}
gradSchemes                                        • This setup is very stable but too diffusive.
{
      default        cellLimited Gauss linear 1;   • This setup is first order in space and time.
      grad(U)        cellLimited Gauss linear 1;
}
                                                   • You can use this setup to start the solution in the
divSchemes                                           presence of bad quality meshes or strong
{
      default                none;
                                                     discontinuities.
      div(phi,U)             Gauss upwind;
                                                   • Remember, you can start using a first order method
      div(phi,omega)         Gauss upwind;
      div(phi,k)             Gauss upwind;           and then switch to a second order method.
      div((nuEff*dev(T(grad(U))))) Gauss linear;
}                                                  • According to the quality of your mesh, you will need
laplacianSchemes                                     to change the blending factor of the
{
      default        Gauss linear limited 0.5;       laplacianSchemes and snGradSchemes
}                                                    keywords.
interpolationSchemes
{                                                  • Start robustly, end with accuracy.
      default        linear;
}
snGradSchemes
                                                   • You can use this method for troubleshooting. If the
{                                                    solution diverges, you better check boundary
}
      default        limited 0.5;
                                                     conditions, physical properties, and so on.
                                                                                                           614
                    Roadmap
                                                  615
                           On the CFL number
•   First of all, what is the CFL or Courant number?
•   In one dimension, the CFL number is defined as,
•   By the way, and this is extremely important, the CFL condition is a necessary
    condition for stability (and hence convergence).
•   But it is not always sufficient to guarantee stability.
•   Other properties of the discretization schemes that you should observe are:
    conservationess, boundedness, transportiveness, and accuracy.
                                                                                    618
                               On the CFL number
                               How to control the CFL number
application      pimpleFoam;             • You can control the CFL number by changing the mesh cell
                                           size or changing the time-step size.
startFrom        latestTime;
maxCo            2.0;
maxDeltaT        0.001;
                                                                                                      619
                               On the CFL number
                               How to control the CFL number
application      pimpleFoam;             • The option adjustTimeStep will automatically adjust the time
                                           step to achieve the maximum desired courant number
startFrom        latestTime;
                                           (maxCo) or time-step size (maxDeltaT).
startTime        0;
stopAt           endTime;
                                         • When any of these conditions is reached, the solver will stop
                                           scaling the time-step size.
endTime          10;
deltaT           0.0001;
                                         • To use these features, you need to turn-on the option
                                           adjustTimeStep.
writeControl     runTime;
writeInterval    0.1;
                                         • Remember, the first time-step of the simulation is done using
                                           the value defined with the keyword deltaT and then it is
purgeWrite       0;
                                           automatically scaled (up or down), to achieve the desired
writeFormat      ascii;                    maximum values (maxCo and maxDeltaT).
writePrecision   8;
                                         • It is recommended to start the simulation with a low time-step
writeCompression off;
                                           in order to let the solver scale-up the time-step size.
timeFormat       general;
                                         • If you want to change the values on-the-fly, you need to turn-
timePrecision    6;
                                           on the option runTimeModifiable.
runTimeModifiable yes;
                                         • The feature adjustTimeStep is only present in the PIMPLE
adjustTimeStep   yes;
                                           family solvers, but it can be added to any solver by modifying
maxCo            2.0;                      the source code.
maxDeltaT        0.001;
                                                                                                       620
                                      On the CFL number
                                                  The output screen
•    This is the output screen of a solver supporting the option adjustTimeStep.
•    In this case maxCo is equal 2 and maxDeltaT is equal to 0.001.
•    Notice that the solver reached the maximum allowable maxDeltaT.
    Courant Number mean: 0.10863988 max: 0.73950028                           Courant number (mean and maximum values)
    deltaT = 0.001                    Current time-step
    Time = 30.000289542261612                                                 Simulation time
    PIMPLE: iteration 1                                                One PIMPLE iteration (outer loop), this is equivalent to PISO
    DILUPBiCG: Solving for Ux, Initial residual = 0.003190933, Final residual = 1.0207483e-09, No Iterations 5
    DILUPBiCG: Solving for Uy, Initial residual = 0.0049140114, Final residual = 8.5790109e-10, No Iterations 5
    DILUPBiCG: Solving for Uz, Initial residual = 0.010705877, Final residual = 3.5464756e-09, No Iterations 4
    GAMG: Solving for p, Initial residual = 0.024334674, Final residual = 0.0005180308, No Iterations 3
    GAMG: Solving for p, Initial residual = 0.00051825089, Final residual = 1.6415538e-05, No Iterations 5
    time step continuity errors : sum local = 8.768064e-10, global = 9.8389717e-11, cumulative = -2.6474162e-07
    GAMG: Solving for p, Initial residual = 0.00087813032, Final residual = 1.6222017e-05, No Iterations 3
    GAMG: Solving for p, Initial residual = 1.6217958e-05, Final residual = 6.4475277e-06, No Iterations 1
    time step continuity errors : sum local = 3.4456296e-10, global = 2.6009599e-12, cumulative = -2.6473902e-07
    ExecutionTime = 33091.06 s ClockTime = 33214 s
                                                                       CPU time and wall clock
    fieldMinMax domainminandmax output:
        min(p) = -0.59404715 at location (-0.019 0.02082288 0.072) on processor 1
        max(p) = 0.18373302 at location (-0.02083962 -0.003 -0.136) on processor 1
        min(U) = (0.29583255 -0.4833922 -0.0048229716) at location (-0.02259661 -0.02082288 -0.072) on processor 0
        max(U) = (0.59710937 0.32913292 0.020043679) at location (0.11338793 -0.03267608 0.12) on processor 3
        min(nut) = 1.6594481e-10 at location (0.009 -0.02 0.024) on processor 0
        max(nut) = 0.00014588174 at location (-0.02083962 0.019 0.072) on processor 1
                                                  622
                  Linear solvers in OpenFOAM®
•   After spatial and temporal discretization and by using equation
    in every control volume      of the domain, a system of linear algebraic equations for the
    transported quantity    is assembled
                                                                                                                   624
                         Linear solvers in OpenFOAM®
                                  Linear solvers – fvSolution dictionary
solvers                                        • In this generic case, to solve the pressure (p) we are using the
{                                                PCG method with the DIC preconditioner, an absolute
  p
  {
                                                 tolerance equal to 1e-06 and a relative tolerance relTol equal
    solver               PCG;                    to 0.
    preconditioner       DIC;
    tolerance            1e-06;                • The entry pFinal refers to the final pressure correction (notice
    relTol               0;                      that we are using macro syntax), and we are using a relative
  }
                                                 tolerance relTol equal to 0 (disabled).
  pFinal
  {                                            • To solve the velocity field (U) we are using the PBiCGStab
        $p;                                      method with the DILU preconditoner, an absolute tolerance
        relTol   0;
    }
                                                 equal to 1e-08 and a relative tolerance relTol equal to 0.
    U
    {
                                               • The linear solvers will iterative until reaching any of the
        solver           PBiCGStab;              tolerance values set by the user or reaching a maximum value
        preconditioner   DILU;                   of iterations (optional entry).
        tolerance        1e-08;
        relTol           0;                    • FYI, solving for the velocity is relatively inexpensive, whereas
    }                                            solving for the pressure is expensive.
}
                                               • The pressure equation is particularly important as it governs
PISO                                             mass conservation.
{
  nCorrectors 2;                               • If you do not solve the equations accurately enough (tolerance),
  nNonOrthogonalCorrectors        1;
                                                 the physics might be wrong.
}
                                               • Selection of the tolerance is of paramount importance and it
                                                 might be problem dependent.
                                                                                                                    625
                         Linear solvers in OpenFOAM®
                                  Linear solvers – fvSolution dictionary
solvers                                        • The linear solvers are iterative, i.e., they are based on reducing
{                                                the equation residual over a succession of solutions.
  p
  {                                            • The residual is a measure of the error in the solution so that the
    solver               PCG;
    preconditioner       DIC;
                                                 smaller it is, the more accurate the solution.
    tolerance            1e-06;
                                               • More precisely, the residual is evaluated by substituting the
    relTol               0;
  }                                              current solution into the equation and taking the magnitude of
  pFinal                                         the difference between the left- and right-hand sides (L2-norm).
  {
        $p;
        relTol   0;
    }
    U
    {
        solver           PBiCGStab;
        preconditioner   DILU;
                                               • It is also normalized to make it independent of the scale of the
        tolerance        1e-08;                  problem being analyzed.
        relTol           0;
    }
}
PISO
{
  nCorrectors 2;
  nNonOrthogonalCorrectors        1;
}
                                                                                                                 626
                         Linear solvers in OpenFOAM®
                                  Linear solvers – fvSolution dictionary
solvers                                        • Before solving an equation for a particular field, the initial
{                                                residual is evaluated based on the current values of the field.
  p
  {                                            • After each solver iteration the residual is re-evaluated. The
    solver               PCG;
    preconditioner       DIC;
                                                 solver stops if either of the following conditions are reached:
    tolerance            1e-06;
                                               • The residual falls below the solver tolerance, tolerance.
    relTol               0;
  }                                            • The ratio of current to initial residuals falls below the solver
  pFinal
  {                                              relative tolerance, relTol.
        $p;                                    • The number of iterations exceeds a maximum number of
        relTol   0;
    }
                                                 iterations, maxIter.
    U
    {
                                               • The solver tolerance should represent the level at which the
        solver           PBiCGStab;              residual is small enough that the solution can be deemed
        preconditioner   DILU;                   sufficiently accurate.
        tolerance        1e-08;
        relTol           0;                    • The keyword maxIter is optional and the default value is 1000.
        minIter          3;
        maxIter          100;                  • The user can also define the minimum number of iterations
    }                                            using the keyword minIter. This keyword is optional, and the
}
                                                 default value is 0.
PISO
{
  nCorrectors 2;
  nNonOrthogonalCorrectors        1;
}
                                                                                                                    627
                      Linear solvers in OpenFOAM®
                                                         Linear solvers
•   These are the linear solvers (segregated) available in OpenFOAM®:
•   You will find the source code of the linear solvers in the following directory:
      •    $WM_PROJECT_DIR/src/OpenFOAM/matrices/lduMatrix/solvers
Time = 50
                                                                                                                          630
                   Linear solvers in OpenFOAM®
                                   Linear solvers tolerances
•   So how do we set the tolerances?
•   The pressure equation is particularly important, so we should resolve it accurately. Solving the
    pressure equation is the expensive part of the whole iterative process.
•   For the pressure equation (symmetric matrix), you can start the simulation with a tolerance
    equal to 1e-6 and relTol equal to 0.01.
•   And after a while, you change these values to 1e-6 and 0.0, respectively.
•   If the linear solver is taking too much time, you can change the convergence criterion to 1e-4
    and relTol equal to 0.05. You usually will do this during the first iterations.
    p                                                     p
    {                                                     {
          solver           PCG;                                solver           PCG;
          preconditioner   DIC;                                preconditioner   DIC;
          tolerance        1e-6;                               tolerance        1e-6;
          relTol           0.01;                               relTol            0.0;
    }                                                     }
                                                                                                       631
                  Linear solvers in OpenFOAM®
                                   Linear solvers tolerances
•   For the velocity field (U) and the transported quantities (asymmetric matrices), you can use the
    following criterion.
•   Solving for these variables is relatively inexpensive, so you can start right away with a tight
    tolerance.
•   As a side note, the relative tolerance (relTol) is the difference between the initial residuals and
    the current final residuals.
     U                                                      U
     {                                                      {
         solver                PBiCGStab;                        solver                PBiCGStab;
         preconditioner        DILU;                             preconditioner        DILU;
         tolerance             1e-8;                             tolerance            1e-8;
         relTol                0.001;                            relTol               0.0;
     }                                                       }
                                                                                                          632
                  Linear solvers in OpenFOAM®
                                  Linear solvers tolerances
•   It is also a good idea to set the minimum number of iterations (minIter), we recommend using a
    value of 3.
•   If your solver is doing too many iterations, you can set the maximum number of iterations
    (maxIter).
•   But be careful, if the solver reach the maximum number of iterations it will stop, we are talking
    about unconverged time-steps or outer-iterations.
•   Setting the maximum number of iterations is especially useful during the first time-steps where
    the linear solver takes longer to converge.
•   You can set minIter and maxIter in all symmetric and asymmetric linear solvers.
                            p
                            {
                                 solver                          PCG;
                                 preconditioner                  DIC;
                                 tolerance                       1e-6;
                                 relTol                          0.01;
                                 minIter                         3;
                                 maxIter                         100;
                            }
                                                                                                        633
                   Linear solvers in OpenFOAM®
                                    Linear solvers tolerances
•   When you use the PISO or PIMPLE method with the momentumPredictor option (which is
    enabled by default), you also have the option to set the tolerance for the final pressure corrector
    step (pFinal).
•   By proceeding in this way, you can put all the computational effort only in the last corrector step
    (pFinal).
•   For all the intermediate corrector steps, you can use a more relaxed convergence criterion.
•   For example, you can use the following solver and tolerance criterion for all the intermediate
    corrector steps (p), then in the final corrector step (pFinal) you tight the solver tolerance.
    p                                                      pFinal
    {                                                      {
          solver           PCG;                                     solver           PCG;
          preconditioner   DIC;                                     preconditioner   DIC;
          tolerance        1e-4;                                    tolerance        1e-6;
          relTol            0.05;                                   relTol            0.0;
    }                                                      }
                                                                                                      634
                        Linear solvers in OpenFOAM®
                                                Linear solvers tolerances
•   When you use the PISO or PIMPLE method with the momentumPredictor option (which is
    enabled by default), you also have the option to set the tolerance for the final pressure corrector
    step (pFinal).
•   By proceeding in this way, you can put all the computational effort only in the last corrector step
    (pFinal in this case).
•   For all the intermediate corrector steps (p), you can use a more relaxed convergence criterion.
•   If you proceed in this way, it is recommended to do at least 2 corrector steps (nCorrectors).
       PIMPLE: iteration 1
       DILUPBiCG: Solving for Ux, Initial residual = 0.0024649332, Final residual = 2.3403547e-09, No Iterations 4
       DILUPBiCG: Solving for Uy, Initial residual = 0.0044355904, Final residual = 1.8966277e-09, No Iterations 4
       DILUPBiCG: Solving for Uz, Initial residual = 0.010100894, Final residual = 1.4724403e-09, No Iterations 4
       GAMG: Solving for p, Initial residual = 0.018497918, Final residual = 0.00058090899, No Iterations 3
1                                                                                                                        p
       GAMG: Solving for p, Initial residual = 0.00058090857, Final residual = 2.5748489e-05, No Iterations 5
       time step continuity errors : sum local = 1.2367812e-09, global = 2.8865505e-11, cumulative = 1.057806e-08
       GAMG: Solving for p, Initial residual = 0.00076032002, Final residual = 2.3965621e-05, No Iterations 3            p
2      GAMG: Solving for p, Initial residual = 2.3961044e-05, Final residual = 6.3151172e-06, No Iterations 2            pFinal
       time step continuity errors : sum local = 3.0345314e-10, global = -3.0075104e-12, cumulative = 1.0575052e-08
       DILUPBiCG: Solving for omega, Initial residual = 0.00073937735, Final residual = 1.2839908e-10, No Iterations 4
       DILUPBiCG: Solving for k, Initial residual = 0.0018291502, Final residual = 8.5494234e-09, No Iterations 3
       ExecutionTime = 29544.18 s ClockTime = 29600 s
nCorrectors
                                                                                                                                  635
                         Linear solvers in OpenFOAM®
                                        Linear solvers – Matrix reordering
•   As we are solving a sparse matrix, the more diagonal the matrix is, the best the convergence
    rate will be.
•   So it is highly advisable to use the utility renumberMesh before running the simulation.
       •    $> renumberMesh –overwrite
•   The utility renumberMesh can dramatically increase the speed of the linear solvers, specially
    during the first iterations.
•   The idea behind reordering is to make the matrix more diagonally dominant, therefore, speeding
    up the iterative solver.
Matrix structure plot before reordering Matrix structure plot after reordering
Note: this is the actual pressure matrix from an OpenFOAM® model case                                            636
                  Linear solvers in OpenFOAM®
                                   On the multigrid solvers
•   The development of multigrid solvers (GAMG in OpenFOAM®), together with the development
    of high-resolution TVD schemes and parallel computing, are among the most remarkable
    achievements of the history of CFD.
•   Most of the time using the GAMG linear solver is fine.
•   However, if you see that the GAMG linear solver is taking too long to converge or is converging
    in more than 100 iterations, it is better to use the PCG linear solver.
•   Particularly, we have found that the GAMG linear solver in OpenFOAM® does not perform very
    well when you scale your computations to more than 500 processors.
•   Also, we have found that for some multiphase cases the PCG method outperforms the GAMG.
•   But again, this is problem and hardware dependent.
•   As you can see, you need to always monitor your simulations (stick to the screen for a while.
•   Otherwise, you might end-up using a solver that is performing poorly, and this translate in
    increased computational time and costs.
                                                                                                    637
                   Linear solvers in OpenFOAM®
                                 On the multigrid solvers tolerances
•   If you go for the GAMG linear solver for symmetric matrices (e.g., pressure), the following
    tolerances are acceptable for most of the cases.
     p                                                          pFinal
     {                                                          {
         solver                    GAMG;                           solver                  GAMG;
         tolerance                 1e-6;                           tolerance               1e-6;
         relTol                    0.01;                           relTol                  0;
         smoother                  GaussSeidel;                    smoother                GaussSeidel;
         nPreSweeps                0;                              nPreSweeps              0;
         nPostSweeps               2;                              nPostSweeps             2;
         cacheAgglomeration        on;                             cacheAgglomeration      on;
         agglomerator              faceAreaPair;                   agglomerator            faceAreaPair;
         nCellsInCoarsestLevel     100;                            nCellsInCoarsestLevel   100;
         mergeLevels               1;                              mergeLevels             1;
         minIter                   3;                              minIter                 3;
     }                                                          }
    NOTE:
    The GAMG parameters are not optimized, that is up to you.
    Most of the times is safe to use the proposed parameters.
                                                                                                           638
                  Linear solvers in OpenFOAM®
                   Linear solvers tolerances – Steady simulations
•   The previous tolerances are fine for unsteady solver.
•   For extremely coupled problems you might need to have tighter tolerances.
•   You can use the same tolerances for steady solvers. However, it is acceptable to use a looser
    criterion.
•   For steady simulations using the SIMPLE method, you can set the convergence controls based
    on residuals of fields.
•   The controls are specified in the residualControls sub-dictionary of the dictionary file
    fvSolution.
                               SIMPLE
                               {
                                   nNonOrthogonalCorrectors      2;
                                     residualControl
                                     {
                                          p 1e-4;                        Residual control for every
                                          U 1e-4;                        field variable you are solving
                                     }
                               }
                                                                                                          639
                   Linear solvers in OpenFOAM®
                      Linear solvers benchmarking of a model case
                                                                                                          641
                    Roadmap
                                                  642
    Pressure-Velocity coupling in OpenFOAM®
•   To solve the Navier-Stokes equations we need to use a solution approach able to
    deal with the nonlinearities of the governing equations and with the coupled set of
    equations.
                                                                                          643
    Pressure-Velocity coupling in OpenFOAM®
•   Many numerical methods exist to solve the Navier-Stokes equations, just to name a
    few:
         •   Pressure-correction methods (Predictor-Corrector type).
                   •   SIMPLE, SIMPLEC, SIMPLER, PISO.
         •   Projection methods.
                   •   Fractional step (operator splitting), MAC, SOLA.
         •   Density-based methods and preconditioned solvers.
                   •   Riemann solvers, ROE, HLLC, AUSM+, ENO, WENO.
         •   Artificial compressibility methods.
         •   Artificial viscosity methods.
•   The most widely used approaches for solving the NSE are:
         •   Pressure-based approach (predictor-corrector).
         •   Density-based approach.
                                                                                    644
    Pressure-Velocity coupling in OpenFOAM®
•   Historically speaking, the pressure-based approach was developed for low-speed
    incompressible flows, while the density-based approach was mainly developed for
    high-speed compressible flows.
•   However, both methods have been extended and reformulated to solve and operate
    for a wide range of flow conditions beyond their original intent.
•   In OpenFOAM®, you will find segregated pressure-based solvers.
•   The segregated pressure-based solvers in OpenFOAM®, solve a modified pressure
    equation (pressure-Poisson equation).
•   The following methods are available:
         • SIMPLE (Semi-Implicit Method for Pressure-Linked Equations)
         • SIMPLEC (SIMPLE Corrected/Consistent)
         • PISO (Pressure Implicit with Splitting Operators)
• You will find the solvers in the following directory:
         • $WM_PROJECT_DIR/applications/solvers
• Additionally, you will find something called PIMPLE, which is a hybrid between
  SIMPLE and PISO (known as iterative PISO outside OpenFOAM® jargon).
        • This formulation can give you more accuracy and stability when using very
           large time-steps or in pseudo-transient simulations.
                                                                                      645
   Pressure-Velocity coupling in OpenFOAM®
• In OpenFOAM®, the PISO and PIMPLE methods are formulated for unsteady
  simulations.
• Whereas, the SIMPLE and SIMPLEC methods are formulated for steady simulations.
• If conserving time is not a priority, you can use the PIMPLE method in pseudo
  transient mode.
• The pseudo transient PIMPLE method is more stable than the SIMPLE method, but it
  has a higher computational cost.
• Also, the pseudo transient PIMPLE method tends to be faster than the fully transient
  PIMPLE when reaching steady states.
• Depending on the method and solver you are using, you will need to define a specific
  sub-dictionary in the dictionary file fvSolution.
• For instance, if you are using the PISO method, you will need to specify the PISO
  sub-dictionary.
• And depending on the method, each sub-dictionary will have different entries.
                                                                                    646
    Pressure-Velocity coupling in OpenFOAM®
                                   On the origins of the methods
•   SIMPLE
         •      S. V. Patankar and D. B. Spalding, “A calculation procedure for heat, mass and momentum
                transfer in three-dimensional parabolic flows”, Int. J. Heat Mass Transfer, 15, 1787-1806 (1972).
•   SIMPLE-C
         •   J. P. Van Doormaal and G. D. Raithby, “Enhancements of the SIMPLE method for predicting
             incompressible fluid flows”, Numerical Heat Transfer, 7, 147-163 (1984).
•   PISO
           •    R. I. Issa, “Solution of the implicitly discretized fluid flow equations by operator-splitting”, J.
                Comput. Phys., 62, 40-65 (1985).
•   PIMPLE
      • Unknown origins outside OpenFOAM® ecosystem (we are referring to the semantics).
      • It is equivalent to PISO with outer iterations (iterative time-advancement of the solution).
      • Useful reference (besides PISO reference):
            • I. E. Barton, “Comparison of SIMPLE and PISO-type algorithms for transient flows, Int. J.
               Numerical methods in fluids, 26,459-483 (1998).
            • P. Oliveira and R. I. Issa, “An improved piso algorithm for the computation of buoyancy-driven
               flows”, Numerical Heat Transfer, 40, 473-493 (2001).
                                                                                                                      647
   Pressure-Velocity coupling in OpenFOAM®
                                The SIMPLE sub-dictionary
• This sub-dictionary is located in the dictionary file fvSolution.
• It controls the options related to the SIMPLE pressure-velocity coupling method.
• The SIMPLE method only makes one correction.
• An additional correction to account for mesh non-orthogonality is available when using the
  SIMPLE method. The number of non-orthogonal correctors is specified by the
  nNonOrthogonalCorrectors keyword.
• The number of non-orthogonal correctors is chosen according to the mesh quality.
• For orthogonal meshes you can use 0 non-orthogonal corrections. However, it is strongly
  recommended to do at least 1 non-orthogonal correction (this helps stabilizing the solution).
• For non-orthogonal meshes, it is recommended to do at least 1 correction.
                                   SIMPLE
                                   {
                                       nNonOrthogonalCorrectors          1;
                                   }
                                                                                                  648
   Pressure-Velocity coupling in OpenFOAM®
                                 The SIMPLE sub-dictionary
• You can use the optional keyword consistent to enable or disable the SIMPLEC method.
• This option is disable by default.
• In the SIMPLEC method, the cost per iteration is marginally higher but the convergence rate is
  better, so the number of iterations is reduced.
• The SIMPLEC method relaxes the pressure in a consistent manner and additional relaxation of
  the pressure is not generally necessary (but it is recommended).
• In addition, convergence of the p-U system is better and still is reliable with less aggressive
  relaxation factors of the momentum equation.
                                       SIMPLE
                                       {
                                           consistent yes;
                                           nNonOrthogonalCorrectors       1;
                                       }
                                                                                                    649
   Pressure-Velocity coupling in OpenFOAM®
                                The SIMPLE sub-dictionary
• These are the typical (or industry standard) under-relaxation factors for the SIMPLE and
  SIMPLEC methods.
• Remember the under-relaxation factors are problem dependent.
SIMPLE SIMPLEC
     relaxationFactors                       relaxationFactors
     {                                       {
          fields                                  fields
          {                                       {
               p         0.3;                          p          1.0;
          }                                       }                                Usually there is no need
                                                                                   to under-relax pressure;
          equations                               equations                        however, it is advisable.
          {                                       {
               U         0.7;                          p          1.0;
               k         0.7;                          U          0.9;
               omega     0.7;                          k          0.9;
          }                                            omega      0.9;
     }                                            }
                                             }
                                                                                                          650
   Pressure-Velocity coupling in OpenFOAM®
                                 The SIMPLE sub-dictionary
SIMPLEC
                                                           relaxationFactors
• If you are planning to use the SIMPLEC method,
                                                           {
  we recommend you to use under-relaxation factors
  that are little bit more smaller that the industry            fields
  standard values.                                              {
                                                                     p         0.7;
• If during the simulation you still have some stability
                                                                }
  problems, try to reduce all the values to 0.5.
                                                                equations
• Remember the under-relaxation factors are                     {
  problem dependent.                                                 p         0.7;
• If you are having convergence problems, it is                      U         0.7;
  recommended to start the simulation with low                       k         0.7;
  values (about 0.3), and then increase the values                   omega     0.7;
  slowly up to 0.7 or 0.9 (for faster convergence).             }
                                                           }
                                                                                      651
   Pressure-Velocity coupling in OpenFOAM®
                                                 The SIMPLE loop in OpenFOAM®
fvVectorMatrix UEqn
(
    fvm::ddt(U) + fvm::div(phi, U) - fvm::laplacian(nu, U)
);
solve(UEqn == -fvc::grad(p));
fvScalarMatrix pEqn
(
   fvm::laplacian(rAU, p) == fvc::div(phiHbyA)
);
U = HbyA – rAU*fvc::grad(p);
                                                                                652
   Pressure-Velocity coupling in OpenFOAM®
                                  The PISO sub-dictionary
• This sub-dictionary is located in the dictionary file fvSolution.
• It controls the options related to the PISO pressure-velocity coupling method.
• The PISO method requires at least one correction (nCorrectors).
• For good accuracy and stability (specially in unstructured meshes), it is recommended to use at
  least 2 nCorrectors.
• An additional correction to account for mesh non-orthogonality is available when using the PISO
  method. The number of non-orthogonal correctors is specified by the
  nNonOrthogonalCorrectors keyword.
• The number of non-orthogonal correctors is chosen according to the mesh quality.
• For orthogonal meshes you can use 0 non-orthogonal corrections. However, it is strongly
  recommended to do at least 1 non-orthogonal correction (this helps stabilizing the solution).
• For non-orthogonal meshes, it is recommended to do at least 1 correction.
                                   PISO
                                   {
                                       nCorrectors 2;
                                       nNonOrthogonalCorrectors          1;
                                   }
                                                                                                    653
   Pressure-Velocity coupling in OpenFOAM®
                                   The PISO sub-dictionary
• You can use the optional keyword momentumPredictor to enable or disable the momentum
  predictor step.
• The momentum predictor helps in stabilizing the solution as we are computing better
  approximations for the velocity.
• It is clear that this will add an extra computational cost, which most of the times is negligible.
• In most of the solvers, this option is enabled by default.
• It is recommended to use this option for highly convective flows (high Reynolds number). If you
  are working with low Reynolds flow or creeping flows it is recommended to turn it off.
• Note that when you enable the option momentumPredictor, you will need to define the linear
  solvers for the variables .*Final (we are using regex notation).
• Also, if you want to use URF you will need to apply then to all field variables (including .*Final).
                                     PISO
                                     {
                                         momentumPredictor   yes;
                                         nCorrectors 2;
                                         nNonOrthogonalCorrectors 1;
                                     }
                                                                                                         654
   Pressure-Velocity coupling in OpenFOAM®
      The PISO loop in OpenFOAM®
(PISO with non-iterative marching – NITA – )
fvVectorMatrix UEqn
(
    fvm::ddt(U) + fvm::div(phi, U) - fvm::laplacian(nu, U)
);
solve(UEqn == -fvc::grad(p));
fvScalarMatrix pEqn
(
   fvm::laplacian(rAU, p) == fvc::div(phiHbyA)
);
U = HbyA – rAU*fvc::grad(p);
                                        PIMPLE
                                        {
                                            momentumPredictor yes;
                                            nOuterCorrectors   1;
                                            nCorrectors 2;
                                            nNonOrthogonalCorrectors          1;
                                        }
                                                                                                                    656
    Pressure-Velocity coupling in OpenFOAM®
                                     The PIMPLE sub-dictionary
• You can use under-relaxation factors (URF) with the PIMPLE solvers.
• By using URF, you will gain more stability in time dependent solutions (as they control the amount of change of
  field variables within the time-step).
• However, if you use too low URF values, your solution might not be time-accurate anymore.
• You can use the same or larger URF values as those for steady simulation.
• Note that when you enable the option momentumPredictor, you will need to define the linear solvers for the
  variables .*Final (we are using regex notation).
• You can assign URF to all variables (including .*Final), to only the intermediate field variables (U, p, k, and so
  on), or to only the .*Final variables (UFinal, pFinal, kFinal, and so on).
• We recommend to use URF in all variables.
                                         PIMPLE
                                         {
                                             momentumPredictor yes;
                                             nOuterCorrectors   1;
                                             nCorrectors 2;
                                             nNonOrthogonalCorrectors           1;
                                         }
                                                                                                                   657
   Pressure-Velocity coupling in OpenFOAM®
     The PIMPLE loop in OpenFOAM®
   (PISO with iterative marching – ITA – )
fvVectorMatrix UEqn
(
    fvm::ddt(U) + fvm::div(phi, U) - fvm::laplacian(nu, U)
);
solve(UEqn == -fvc::grad(p));
fvScalarMatrix pEqn
(
   fvm::laplacian(rAU, p) == fvc::div(phiHbyA)
);
U = HbyA – rAU*fvc::grad(p);
                                                             658
    Pressure-Velocity coupling in OpenFOAM®
    Comparison of PISO with non-iterative time-advancement (PISO-NITA)
        against PISO with Iterative time-advancement (PISO-ITA)
•   The main difference between both methods is the outer loop present in the PISO-ITA.
•   This outer loop gives more stability and allow the use of very large time-steps (CFL numbers).
•   The recommended CFL number of the PISO-NITA is below 2 (for good accuracy and stability).
                                                  660
              Unsteady and steady simulations
                                                             Sliding grids – Continuous stirred tank reactor
•   Nearly all flows in nature and industrial applications   www.wolfdynamics.com/wiki/FVM_uns/ani5.gif
    are unsteady (also known as transient or
    time-dependent).
•   Unsteadiness can be due to:
      • Instabilities.
      • Non-equilibrium initial conditions.
      • Time-dependent boundary conditions.                               Multiphase flow
                                                             www.wolfdynamics.com/wiki/FVM_uns/ani3.gif
      • Source terms.
      • Chemical reactions and finite rate chemistry.
      • Phase change.
      • Moving or deforming bodies.
      • Turbulence.
      • Buoyancy and heat transfer.
      • Discontinuities.
                                                                       Turbulent flows - SRS
      • Multiple phases.                                     www.wolfdynamics.com/wiki/FVM_uns/ani4.gif
                                                                                                           661
                 Unsteady and steady simulations
                   How to run unsteady simulations in OpenFOAM®?
•   Select the time step. The time-step must be chosen in such a way that it resolves the time-dependent features
    and maintains solver stability.
•   Select the temporal discretization scheme.
•   Set the tolerance (absolute and/or relative) of the linear solvers.
•   Monitor the CFL number.
•   Monitor the stability and boundedness of the solution.
•   Monitor a quantity of interest.
•   And of course, you need to save the solution with a given frequency.
•   Have in mind that unsteady simulations generate a lot of data.
•   End time of the simulation?, it is up to you.
•   In the controlDict dictionary you need to set runtime parameters and general instructions on how to run the
    case (such as time step and maximum CFL number). You also set the saving frequency.
•   In the fvSchemes dictionary you need to set the temporal discretization scheme.
•   In the fvSolution dictionary you need to set the linear solvers.
•   Also, you will need to set the number of corrections of the velocity-pressure coupling method used (e.g. PISO
    or PIMPLE), this is done in the fvSolution dictionary.
•   Additionally, you may set functionObjects in the controlDict dictionary. The functionObjects are used to
    do sampling, probing and co-processing while the simulation is running.
                                                                                                               662
                  Unsteady and steady simulations
                   How to run unsteady simulations in OpenFOAM®?
divSchemes
{
     default      none;
     div(phi,U)    Gauss linear;
}
laplacianSchemes
{
     default   Gauss linear orthogonal;
}
interpolationSchemes
{
      default    linear;
}
snGradSchemes
{
    default   orthogonal;
}
                                                                                                           663
                      Unsteady and steady simulations
                       How to run unsteady simulations in OpenFOAM®?
writeControl    runTime;               • It will write the solution every 0.1 seconds (writeInterval) of
                                         simulation time (runTime).
writeInterval 0.1;
                                       • The time step of the simulation is 0.0001 seconds (deltaT).
purgeWrite      0;
                                       • It will keep all the solution directories (purgeWrite).
writeFormat      ascii;
                                       • It will save the solution in ascii format (writeFormat) with a
writePrecision 8;                        precision of 8 digits (writePrecision).
writeCompression off;                  • And as the option runTimeModifiable is on (yes), we can
                                         modify all these entries while we are running the simulation.
timeFormat       general;
                                       • To reduce parsing time and file size, it is recommended to use
timePrecision 6;
                                         binary format to write the solution.
runTimeModifiable         yes;
adjustTimeStep            yes;
maxCo                     2.0;
maxDeltaT                 0.001;
                                                                                                           664
                      Unsteady and steady simulations
                       How to run unsteady simulations in OpenFOAM®?
startFrom       latestTime;            • In this generic case, the solver supports adjustable time-step
                                         (adjustTimeStep).
startTime      0;
                                       • The option adjustTimeStep will automatically adjust the time
stopAt         endTime;
                                         step to achieve the maximum desired courant number (maxCo)
endTime         10;                      or time-step size (maxDeltaT).
deltaT       0.0001;                   • When any of these conditions is reached, the solver will stop
                                         scaling the time-step size.
writeControl    runTime;
                                       • Remember, the first time-step of the simulation is done using the
writeInterval 0.1;                       value defined with the keyword deltaT and then it is
purgeWrite      0;
                                         automatically scaled (up or down), to achieve the desired
                                         maximum values (maxCo and maxDeltaT).
writeFormat      ascii;
                                       • It is recommended to start the simulation with a low time-step in
writePrecision 8;                        order to let the solver scale-up the time-step size.
writeCompression off;                  • The feature adjustTimeStep is only present in the PIMPLE
                                         family solvers, but it can be added to any solver by modifying
timeFormat       general;
                                         the source code.
timePrecision 6;
                                       • If you are planning to use large time steps (CFL much higher
runTimeModifiable         yes;           than 1), it is recommended to do at least 3 correctors steps
                                         (nCorrectors) in PISO/PIMPLE loop, and at least 2 outer
adjustTimeStep            yes;
maxCo                     2.0;
                                         correctors in the PIMPLE loop.
maxDeltaT                 0.001;
                                                                                                          665
                    Unsteady and steady simulations
                     How to run unsteady simulations in OpenFOAM®?
solvers                                 • The fvSolution dictionary contains the instructions of how to
{
  p
                                          solve each discretized linear equation system.
  {                                     • As for the controlDict and fvSchemes dictionaries, the
    solver            PCG;
    preconditioner    DIC;                parameters can be changed on-the-fly.
    tolerance         1e-06;
    relTol            0;                • To set these parameters, follow the guidelines given in the
  }                                       previous section.
  pFinal
                                        • Depending on the solver you are using, you will need to define
  {                                       the sub-dictionary PISO or PIMPLE.
      $p;
                                        • Setting the keyword nOuterCorrectors to 1 in PIMPLE solvers
      relTol   0;
  }                                       is equivalent to running using the PISO method.
                                        • To gain more stability, especially when using large time-steps,
  “U.*”
  {
                                          you can use more outer correctors (nOuterCorrectors).
    solver            smoothSolver;
                                        • If you are using large time steps (CFL much higher than 1), it is
    smoother          symGaussSeidel;
    tolerance         1e-08;              recommended to do at least 3 correctors steps (nCorrectors) in
    relTol            0;                  PISO/PIMPLE loop.
  }
}                                       • Remember, in both PISO and PIMPLE method you need to do
PIMPLE                                    at least one correction (nCorrectors).
{
  nOuterCorrectors 1;                   • Adding corrections increase the computational cost
  nCorrectors 2;
  nNonOrthogonalCorrectors     1;
                                          (nOuterCorrectors and nCorrectors).
}
                                                                                                            666
              Unsteady and steady simulations
    How to choose the time-step in unsteady simulations and monitor the solution
•    Remember, when running unsteady simulations the time-step must be chosen in such a way
     that it resolves the time-dependent features and maintains solver stability.
                                                                                                      667
              Unsteady and steady simulations
                             Monitoring unsteady simulations
•   When running unsteady simulations, it is highly advisable to monitor a quantity of interest.
•   The quantity of interest can fluctuate in time, this is an indication of unsteadiness.
                                                                                                   668
               Unsteady and steady simulations
                               What about steady simulations?
•   First of all, steady simulations are a big simplification of reality.
•   Steady simulations is a trick used by CFDers to get fast outcomes with results that might be
    even more questionable.
•   Remember, most of the flows you will encounter are unsteady so be careful of this hypothesis.
•   In steady simulations, we made two assumptions:
     •   We ignore unsteady fluctuations. That is, we neglect the time derivative in the governing
         equations.
     •   We perform time averaging when dealing with stationary turbulence (RANS modeling)
•   The advantage of steady simulations is that they require low computational resources, give fast
    outputs, and are easier to post-process and analyze.
•   To do so, you need to use the appropriate solver and use the right discretization scheme.
•   As you are not solving the time derivative, you do not need to set the time step. However, you
    need to tell OpenFOAM® how many iterations you would like to run.
•   You can also set the residual controls (residualControl), in the fvSolution dictionary file.
    You set the residualControl in the SIMPLE sub-dictionary.
•   If you do not set the residual controls, OpenFOAM® will run until reaching the maximum
    number of iterations (endTime).
                                                                                                   669
              Unsteady and steady simulations
                 How to run steady simulations in OpenFOAM®?
•   In the controlDict dictionary you need to set runtime parameters and general instructions on
    how to run the case (such as the number of iterations to run).
•   Remember to set also the saving frequency.
•   In the fvSchemes dictionary you need to set the time discretization scheme, for steady
    simulations it must be steadyState.
•   In the fvSolution dictionary you need to set the linear solvers, under-relaxation factors, and
    residual controls.
•   Also, you will need to set the number of corrections of the velocity-pressure coupling method
    used (e.g. SIMPLE or SIMPLEC), this is done in the fvSolution dictionary.
•   Additionally, you may set functionObjects in the controlDict dictionary.
•   The functionObjects are used to do sampling, probing and co-processing while the simulation
    is running.
                                                                                                    670
               Unsteady and steady simulations
                  How to run steady simulations in OpenFOAM®?
•   Under-relaxation is a feature typical of steady solvers using the SIMPLE family of methods.
•   These are the URF commonly used with SIMPLE and SIMPLEC (industry standard),
SIMPLE SIMPLEC
       U                0.7;               U                0.9;
       k                0.7;               k                0.9;
       omega            0.7;               omega            0.9;
•   According to the physics involved you will need to add more under-relaxation factors.
•   Finding the right URF involved experience and some trial and error.
•   Selecting the URF it is kind of equivalent to selecting the right time step.
•   Many times, steady simulations diverge because of wrongly chosen URF.                                               671
              Unsteady and steady simulations
                 How to run steady simulations in OpenFOAM®?
•   An optimum choice of under-relaxation factors is one that is small enough to ensure stable
    computation but large enough to move the iterative process forward quickly.
•   Under-relaxation can be implicit (equation in OpenFOAM) or explicit (field in OpenFOAM).
interpolationSchemes
{
      default    linear;                  • This term removes a component proportional to the continuity
}
                                            error. This acts as a convergence aid to tend towards a bounded
snGradSchemes                               solution as the calculation proceeds.
{
    default   orthogonal;                 • At convergence, this term becomes zero and does not
}                                           contribute to the final solution.
                                                                                                           673
                     Unsteady and steady simulations
                            How to run steady simulations in OpenFOAM®?
writeControl      runTime;                 • This generic case starts from iteration 0 (startTime), and it will
                                             run up to 10000 iterations (endTime).
writeInterval 100;
                                           • It will write the solution every 100 iterations (writeInterval) of
purgeWrite        10;                        simulation time (runTime).
writeFormat        ascii;                  • It will advance the solution one iteration at a time (deltaT).
writePrecision 8;                          • It will keep the last 10 saved solutions (purgeWrite).
writeCompression off;                      • It will save the solution in ascii format (writeFormat) with a
                                             precision of 8 digits (writePrecision).
timeFormat         general;
                                           • And as the option runTimeModifiable is on (true), we can
timePrecision 6;
                                             modify all these entries while we are running the simulation.
runTimeModifiable           yes;
                                                                                                                  674
                    Unsteady and steady simulations
                      How to run steady simulations in OpenFOAM®?
solvers                                 • The fvSolution dictionary contains the instructions of how to
{
  p
                                          solve each discretized linear equation system.
  {                                     • As for the controlDict and fvSchemes dictionaries, the
    solver            PCG;
    preconditioner    DIC;                parameters can be changed on-the-fly.
    tolerance         1e-06;
    relTol            0;                • To set these parameters, follow the guidelines given in the
  }                                       previous section.
    U
                                        • Increasing the number of nNonOrthogonalCorrectors
    {                                     corrections will add more stability but at a higher computational
        solver        smoothSolver;       cost.
        smoother      symGaussSeidel;
        tolerance     1e-08;            • Remember, nNonOrthogonalCorrectors is used to improve
        relTol        0;                  the gradient computation due to mesh quality.
    }
}                                       • The SIMPLE sub-dictionary also contains convergence controls
                                          based on residuals of fields. The controls are specified in the
SIMPLE
{
                                          residualControls sub-dictionary.
  nNonOrthogonalCorrectors     2;
                                        • The user needs to specify a tolerance for one or more solved
    residualControl                       fields and when the residual for every field falls below the
    {                                     corresponding residual, the simulation terminates.
      p 1e-4;
      U 1e-4;                           • If you do not set the residualControls, the solver will iterate
    }                                     until reaching the maximum number of iterations set in the
}
                                          controlDict dictionary.
                                                                                                            675
                Unsteady and steady simulations
                    How to run steady simulations in OpenFOAM®?
                                   • The fvSolution dictionary also contains the
relaxationFactors                    relaxationFactors sub-dictionary.
{
   fields                          • The relaxationFactors sub-dictionary which controls under-
   {                                 relaxation, is a technique used for improving stability when using
      p 0.3;
   }
                                     steady solvers.
   equations
   {
                                   • Under-relaxation works by limiting the amount which a variable
      U 0.7;                         changes from one iteration to the next, either by modifying the
   }                                 solution matrix and source prior to solving for a field (equations
}
                                     keyword) or by modifying the field directly (fields keyword).
                                   • Under-relaxing the equations is also known as implicit under-
                                     relaxation.
                                   • Whereas, under-relaxing the fields is also known as explicit
                                     under-relaxation.
                                   • An optimum choice of under-relaxation factors is one that is
                                     small enough to ensure stable computation but large enough to
                                     move the iterative process forward quickly.
                                   • In this case we are using the industry standard URF.
                                   • Remember, URF are problem dependent.
                                   • If you do not define URF, the solver will not under-relax.
                                                                                                     676
              Unsteady and steady simulations
                   How to run steady simulations in OpenFOAM®?
•   To enable the consistent formulation of the SIMPLE method, you need to add the following
    keywork to the SIMPLE sub-dictionary,
                    SIMPLE
                    {
                                                                         Enabled/disabled consistent formulation of the
                         consistent yes;                                 SIMPLE loop
                         nNonOrthogonalCorrectors   3;
                    }
                                                                                                  678
                    Roadmap
                                                  679
                        Understanding residuals
•   Before talking about residuals, let us clarify something.
•   When we talk about iterations in unsteady simulations, we are talking about the time-step or
    outer-iterations.
                                                                                                                     680
                                Understanding residuals
•   To get a better idea of how iterative methods work, and what are initial residuals and final residuals, let us
    take another look at a residual plot.
                                                                                                                                       682
                            Understanding residuals
•   Remember, residuals are not a direct indication that you are converging to the right solution.
•   It is better to monitor a quantity of interest (QOI).
•   And by the way, you should get physically realistic values.
•   In this case, if you monitor the residuals you might get the impression that the simulation is diverging.
•   Instead, if you monitor a QOI you will realize that there is an initial transient (long one by the way), then the
    onset of an instability, and then a periodic behavior of the phenomenon.
•   You should assess the convergence of the solution and compute the unsteady statistics in the time window
    where the behavior of the QOI is periodic.
•   To monitor the stability, you can check the minimum and maximum values of the field variables.
•   If you have bounded quantities, check that you do not have over-shoots or under-shoots.
Residuals QOI
                                                                                                                        683
                             Understanding residuals
•   This is the output of the residuals for all field       •   This is the output of the residuals for all field
    variables of an unsteady case.                              variables of a steady case.
•   Notice that at the beginning the residuals show a       •   The jumps are due to the changes in tolerance
    monotonic behavior.                                         introduced while running the simulation.
•   Then, after a while the convergence rate changes.       •   As you can see, the residuals are falling in a
                                                                monotonic way.
•   This not necessarily means that the solution is
    diverging, it might be an indication of unsteadiness.
                                                                                                                    684
                       Understanding residuals
•   This is the output of the aerodynamic   •   This is the output of the aerodynamic
    coefficients for an unsteady case.          coefficients for a steady case.
                                                                                        685
                    Roadmap
                                                  686
    Boundary conditions and initial conditions
                    On the initial boundary value problem (IBVP)
•   First of all, when we use a CFD solver to find the approximate solution of the governing
    equations, we are solving an Initial Boundary Value Problem (IBVP).
•   In an IBVP, we need to impose appropriate boundary conditions and initial conditions.
•   No need to say that the boundary conditions and initial conditions need to be physically realistic.
•   Boundary conditions are a required component of the numerical method, they tell the solver
    what is going on at the boundaries of the domain.
•   You can think of boundary conditions as source terms.
•   Initial conditions are also a required component of the numerical method, they define the initial
    state of the problem.
                                                                                                    687
    Boundary conditions and initial conditions
                         A few words about boundary conditions
•   Boundary conditions (BC) can be divided into three fundamental mathematical types:
      •   Dirichlet boundary conditions: when we use this BC, we prescribe the value of a variable at the
          boundary.
      •   Neumann boundary conditions: when we use this BC, we prescribe the gradient normal to the
          boundary.
      •   Robin Boundary conditions: this BC is a mixed of Dirichlet boundary conditions and Neumann
          boundary
•   You can use any of these three boundary conditions in OpenFOAM®.
•   During this discussion, the semantics is not important, that depends of how you want to call the BCs or how
    they are named in the solver, i.e., in, inlet, inflow, velocity inlet, incoming flow and so on.
•   Defining boundary conditions involves:
      •   Finding the location of the boundary condition in the domain.
      •   Determining the boundary condition type.
      •   Giving the required physical information.
•   The choice of the boundary conditions depend on:
      •   Geometrical considerations.
      •   Physics involved.
      •   Information available at the boundary condition location.
      •   Numerical considerations.
•   And most important, you need to understand the physics involved.
                                                                                                                  688
    Boundary conditions and initial conditions
                       A few words about boundary conditions
•   To define boundary conditions you need to know the location of the boundaries (where they are
    in your mesh).
•   You also need to supply the information at the boundaries.
•   Last but not least important, you must know the physics involved.
                                                                                               689
    Boundary conditions and initial conditions
                                A few words about initial conditions
•   Initial conditions (IC) can be divided into two groups:
      •     Uniform initial conditions.
      •     Non-uniform initial conditions.
                                                                                                           691
    Boundary conditions and initial conditions
•   Inlets and outlets boundary conditions:
     •   Inlets are for regions where inflow is expected; however, inlets might support outflow when
         a velocity profile is specified.
     •   Pressure boundary conditions do not allow outflow at the inlets.
     •   Velocity specified inlets are intended for incompressible flows.
     •   Pressure and mass flow inlets are suitable for compressible and incompressible flows.
     •   Same concepts apply to outlets, which are regions where outflow is expected.
                                                                                                  692
    Boundary conditions and initial conditions
•   Zero gradient (Neumann) and backflow boundary conditions:
     •   Zero gradient boundary conditions extrapolates the values from the domain. They require
         no information.
     •   Zero gradient boundary conditions can be used at inlets, outlets, and walls.
     •   Backflow boundary conditions provide a generic outflow/inflow condition, with specified
         inflow/outflow for the case of backflow.
     •   In the case of a backflow outlet, when the flux is positive (out of domain) it applies a
         Neumann boundary condition (zero gradient), and when the flux is negative (into of
         domain), it applies a Dirichlet boundary condition (fixed value).
     •   Same concept applies to backflow inlets.
                                                                                                    693
    Boundary conditions and initial conditions
•   On the outlet pressure boundary condition
     •    Some combinations of boundary conditions are very stable, and some are less reliable.
     •    And some configurations are unreliable.
            •     Inlet velocity at the inlet and pressure zero gradient at the outlet. This combination
                  should be avoided because the static pressure level is not fixed.
     •    Qualitatively speaking, the results are very different.
     •    This simulation will eventually crash.
         BCs 1. Inlet velocity and fixed outlet pressure          BCs 2. Inlet velocity and zero gradient outlet pressure
         www.wolfdynamics.com/wiki/BC/aniBC1.gif                  www.wolfdynamics.com/wiki/BC/aniBC2.gif
                                                                                                                            694
    Boundary conditions and initial conditions
•   On the outlet pressure boundary condition
     •   If you only rely on a QOI and the residuals, you will not see any major difference between
         the two cases with different outlet pressure boundary condition.
     •   This is very misleading.
     •   However, when you visualize the solution you will realize that something is wrong. This is
         a case where pretty pictures can be used to troubleshoot the solution.
     •   Quantitative speaking, the results are very similar.
     •   However, this simulation will eventually crash.
Residual plot for pressure Quantity of interest – Force coefficient on the body
                                                                                                                  695
    Boundary conditions and initial conditions
•   Symmetry boundary conditions:
     •   Symmetry boundary conditions are a big simplification of the problem. However, they help
         to reduce mesh cell count.
     •   Have in mind that symmetry boundary conditions only apply to planar faces.
     •   To use symmetry boundary conditions, both the geometry and the flow field must be
         symmetric.
     •   Mathematically speaking, setting a symmetry boundary condition is equivalent to zero
         normal velocity at the symmetry plane, and zero normal gradients of all variables at the
         symmetry plane.
     •   Physically speaking, they are equivalent to slip walls.
                                                                                                    696
    Boundary conditions and initial conditions
•   Location of the outlet boundary condition:
     •   Place outlet boundary conditions as far as possible from recirculation zones or backflow
         conditions, by doing this you increase the stability.
     •   Remember, backflow conditions requires special treatment.
                                               Far enough so the flow can be
             Possible backflow   Might be OK
                                               considered fully developed
                                                                                                    697
    Boundary conditions and initial conditions
•   Domain dimensions (when the dimensions are not known):
     • If you do not have any constrain in the domain dimensions, you can use as a general guideline the
       dimensions illustrated in the figure below, where L is a reference length (in this case, L is the wing chord).
     • The values illustrated in the figure are on the conservative side, nut if you want to play safe, multiply the
       values by two or more.
     • Always verify that there are no significant gradients normal to any of the boundaries patches. If there are,
       you should consider increasing the domain dimensions.
                                                                                                                       698
    Boundary conditions and initial conditions
                              A few considerations and guidelines
• Boundary conditions and initial conditions need to be physically realistic.
• Poorly defined boundary conditions can have a significant impact on your solution.
• Initial conditions are as important as the boundary conditions.
• A good initial condition can improve the stability and convergence rate.
• On the other hand, unphysical initial conditions can slow down the convergence rate or can cause divergence.
• You need to define boundary conditions and initials conditions for every single variable you are solving.
• Setting the right boundary conditions is extremely important, but you need to understand the physics.
• You need to understand the physics in order to set the right boundary conditions.
• Do not force the flow at the outlet, use a zero normal gradient for all flow variables except pressure. The solver
  extrapolates the required information from the interior.
• Be careful with backward flow at the outlets (flow coming back to the domain) and backward flow at inlets
  (reflection waves), they required special treatment.
• If possible, select inflow and outflow boundary conditions such that the flow either goes in or out normal to the
  boundaries.
• At outlets, use zero gradient boundary conditions only with incompressible flows and when you are sure that the
  flow is fully developed.
• Outlets that discharge to the atmosphere can use a static pressure boundary condition. This is interpreted as
  the static pressure of the environment into which the flow exhausts.
                                                                                                                  699
    Boundary conditions and initial conditions
                              A few considerations and guidelines
• Inlets that take flow into the domain from the atmosphere can use a total pressure boundary condition (e.g.
  open window).
• Mass flow inlets produce a uniform velocity profile at the inlet.
• Pressure specified boundary conditions allow a natural velocity profile to develop.
• The required values of the boundary conditions and initial conditions depend on the equations you are solving,
  and physical models used, e.g.,
      • For incompressible and laminar flows you will need to set only the velocity and pressure.
      • If you are solving a turbulent compressible flow you will need to set velocity, pressure, temperature and
        the turbulent variables.
      • For multiphase flows you will need to set the primitives variables for each phase. You will also need to
        initialize the phases.
      • If you are doing turbulent combustion or chemical reactions, you will need to define the species, reactions
        and turbulent variables.
• Minimize grid skewness, non-orthogonality, growth rate, and aspect ratio near the boundaries. You do not want
  to introduce diffusion errors early in the simulation, especially close to the inlets.
• Try to avoid large gradients in the direction normal to the boundaries and near inlets and outlets.
      • That is to say, put your boundaries far away from where things are happening.
                                                                                                                    700
       Boundary conditions and initial conditions
•      OpenFOAM® distinguish between base type boundary conditions and numerical type
       boundary conditions.
    • Base type boundary conditions are based on geometry         • Numerical type boundary condition assigns the value to the
      information (surface patches) or on inter-processor           field variables in the given surface patch.
      communication link (halo boundaries).
                                                                  • Numerical type boundary conditions are defined in the field
    • Base type boundary conditions are defined in the file         variables dictionaries located in the directory 0 (e.g. U, p).
      boundary located in the directory constant/polyMesh
                                                                  • When we talk about numerical type boundary conditions, we
    • The file boundary is automatically created when you           are referring to Dirichlet, Neumann or Robin boundary
      generate or convert the mesh.                                 conditions.
    • When you convert a mesh to OpenFOAM® format, you            • You need to manually create the field variables dictionaries
      might need to manually modify the file boundary. This is      (e.g. 0/U, 0/p, 0/T, 0/k, 0/omega).
      because the conversion utilities do not recognize the
      boundary type of the original mesh.                         • Remember, if you forget to define a numerical boundary
                                                                    condition, OpenFOAM® will complain and will tell you where
    • Remember, if a base type boundary condition is missing,       and what is the error.
      OpenFOAM® will complain and will tell you where and what
      is the error.                                               • Also, if you misspelled something OpenFOAM® will complain
                                                                    and will tell you where and what is the error.
    • Also, if you misspelled something OpenFOAM® will complain
      and will tell you where and what is the error
                                                                                                                                     701
      Boundary conditions and initial conditions
•     The following base type and numerical type boundary conditions are constrained or paired.
•     That is, the type needs to be same in the boundary dictionary and field variables dictionaries
      (e.g. 0/U, 0/p, 0/T, 0/k, 0/omega).
                             cyclic                                                          cyclic
                           cyclicAMI                                                      cyclicAMI
                             empty                                                           empty
                          processor                                                       processor
                           symmetry                                                       symmetry
                       symmetryPlane                                                   symmetryPlane
                             wedge                                                          wedge
                                                                           advective
                                                                          calculated
                                                                      codedFixedValue
                                                                     epsilonWallFunction
                                                                          fixedValue
                                                                          inletOutlet
                                                                     movingWallVelocity
                      patch
                                                                     rotatingWallVelocity
                                                                              slip
                                                                    supersonicFreeStream
                                                                        totalPressure
                                                                         zeroGradient
                                                                               … and so on
                                                   Refer to the doxygen documentation or the source code for a list of all
                                                                 numerical boundary conditions available.
                                                                                                                             703
    Boundary conditions and initial conditions
•   The wall base type boundary condition is defined as follows:
                                                 type fixedValue;
                       wall                                                          zeroGradient
                                                 value uniform (0 0 0);
•   This boundary condition is not contained in the patch base type boundary conditions group,
    because specialize modeling options can be used on this boundary condition.
•   An example is turbulence modeling, where turbulence can be generated or dissipated at the
    walls.
                                                                                                    704
    Boundary conditions and initial conditions
•   To deal with backflow at outlets, you can use the following boundary condition:
                                      type inletOutlet;
                                                                       type fixedValue;
                patch                 inletValue uniform (0 0 0);
                                                                       value uniform 0;
                                      value uniform (0 0 0);
                                                                                                       705
     Boundary conditions and initial conditions
•   Typical boundary conditions are as follows (external aerodynamics),
* Wall functions can be: kqWallFunction, omegaWallFunction, nutkWallFunction, and so on (next slide).
                                                                                                                 706
    Boundary conditions and initial conditions
•   Typical wall functions boundary conditions are as follows,
                                                                            zeroGradient or fixedValue 0 or
    epsilon                             epsilonWallFunction
                                                                            a small number
                                                                            omegaWallFunction or
    omega                               omegaWallFunction
                                                                            fixedValue with a big number
                                                                                                                 707
    Boundary conditions and initial conditions
•   Finally, remember that the name of the base type boundary condition and the name of the
    numerical type boundary condition needs to be the same, if not, OpenFOAM® will complain.
•   Pay attention to this, specially if you are converting the mesh from another format.
•   Also, do not use spaces of funny characters when assigning the names to the boundary
    patches.
•   The following names are consistent among all dictionary files,
                                                                                                  708
    Boundary conditions and initial conditions
•   There is a plethora of boundary conditions implemented in OpenFOAM®.
•   You can find the source code of the main numerical boundary conditions in the following directory:
     •   $WM_PROJECT_DIR/src/finiteVolume/fields/
•   The wall boundary conditions for the turbulence models (wall functions), are located in the following directory:
     •   $WM_PROJECT_DIR/src/MomentumTransportModels/momentumTransportModels/derivedF
         vPatchFields/wallFunctions
•   To find all the boundary conditions implemented in OpenFOAM, go to the directory $WM_PROJECT_DIR and
    type in the terminal,
     •   $> find . -type d -iname *fvPatch*
•   To get more information about all the boundary conditions available in OpenFOAM® you can read the
    Doxygen documentation.
    3
    (
                                                                      movingWall
         movingWall                           frontAndBack
         {
             type          patch;
             nFaces        20;
             startFace     760;
         }
fixedWalls
                                                                                          fixedWalls
                                                   fixedWalls
         {
             type          wall;
             nFaces        60;
             startFace     780;
         }
         frontAndBack
         {
             type          empty;
             nFaces        800;                                                     frontAndBack
             startFace     840;
         }
                                                                       fixedWalls
                                                                                                       710
        Boundary conditions and initial conditions
                         The constant/polyMesh/boundary dictionary
•       For a generic case, the file boundary is divided as follows
                                                                                movingWall
    dimensions          [0 1 -1 0 0 0 0];                                       type fixedValue;
                                                                                value uniform (1 0 0);
    internalField       uniform (0 0 0);
    boundaryField                                    frontAndBack
    {                                                type empty;
                                                                                                               type fixedValue;
            type                fixedValue;
                                                                                                               fixedWalls
                                                       type fixedValue;
         fixedWalls
         {
                                                       fixedWalls
             type               fixedValue;
             value              uniform (0 0 0);
         }
         frontAndBack
         {                                                                                                frontAndBack
             type               empty;
                                                                                                          type empty;
         }
    }
                                                                                 fixedWalls
                                                                                 type fixedValue;
                                                                                 value uniform (0 0 0);
                                                                                                                              712
        Boundary conditions and initial conditions
                                                The 0/p dictionary
•       For a generic case, the numerical type BC are assigned as follows (p),
    boundaryField                                 frontAndBack
    {                                             type empty;
                                                                                                      type zeroGradient;
        movingWall
        {
            type                zeroGradient;
        }
type zeroGradient;
                                                                                                      fixedWalls
         fixedWalls
         {
             type               zeroGradient;        fixedWalls
         }
         frontAndBack
         {
             type               empty;
         }                                                                                      frontAndBack
    }
                                                                                                type empty;
                                                                           fixedWalls
                                                                           type zeroGradient;
                                                                                                                    713
                    Roadmap
                                                  714
            Numerical playground
Merry-go-round:
Pure convection of a passive scalar in a vector
field – One dimensional tube.
                                                  715
                     Numerical playground
• This is a visual and mental exercise only.
$PTOFC/101FVM/pureConvection/orthogonal_1d
• In this directory, you will also find the README.FIRST file with the
  instructions of how to run the case.
                                                                         716
                          Numerical playground
Pure convection of a scalar in a vector field – One dimensional tube.
                                U = zeroGradient
                                T = zeroGradient
  U = (1 0 0)                                                       U = zeroGradient
  T=1                                                               T = zeroGradient
                (0 0 0)                                   (1 0 0)
                                U = zeroGradient
                                T = zeroGradient
                                                   Initial conditions
                                                   U = (1 0 0)
                                                   T=0
                                                                                       717
                           Numerical playground
•   This problem has an exact solution in the form of a traveling wave.
•   We will use this case to study the different discretization schemes implemented in
    OpenFOAM®.
•   In the figure, we show the solution for time = 0.5 s
www.wolfdynamics.com/wiki/pureconvection/xani1.gif
www.wolfdynamics.com/wiki/pureconvection/xani2.gif
                                                                                                                 718
                             Numerical playground
Comparison of different spatial discretization schemes.   Comparison of different spatial discretization schemes.
        Euler in time – 100 cells – CFL = 0.1                     Euler in time – 100 cells – CFL = 0.1
   Linear limiter functions on the Sweby diagram.          Non-linear limiter functions on the Sweby diagram.
                                                                                                              719
                            Numerical playground
     Comparison of different gradient limiters.             Comparison of different gradient limiters.
Linear upwind in space – Euler in time – 100 cells –   Linear upwind in space – Euler in time – 100 cells –
                     CFL 0.1                                                CFL 0.1
                                                                                                          720
                           Numerical playground
Comparison of different time discretization schemes   Comparison of Crank Nicolson blending factor using
              and gradient limiters.                    cellLimited leastSquares 0.5 gradient limiter.
  Linear upwind in space – 100 cells – CFL 0.1          Linear upwind in space – 100 cells – CFL 0.1
                                                                                                      721
                            Numerical playground
Comparison of different time-step size (different CFL    Comparison of different mesh sizes.
                     number).                           Linear upwind in space – Euler in time
 Linear upwind in space – Euler in time – 100 cells
                                                                                                 722
                           Numerical playground
•   This case was for your eyes and brain only, but we encourage you to reproduce all the previous
    results,
          •   Use all the time discretization schemes.
          •   Use all the spatial discretization schemes.
          •   Use all the gradient discretization schemes.
          •   Use gradient limiters.
          •   Use different mesh resolution.
          •   Use different time-steps.
                                                                                                723
                              Numerical playground
                                                  Exercises
•   Which one of the following schemes is useless: upwind, downwind, or linear
•   Compare the solution obtained with the following schemes: upwind, linearUpwind, MUSCL, QUICK, cubic,
    UMIST, OSHER, Minmod, vanAlbada. Are all of them bounded? Are they second order accurate?
•   Use the linearUpwind method with Gauss linear, Gauss pointLinear and leastSquares for gradient
    computations, which method is more accurate?
•   Imagine that you are using the linearUpwind method with no gradient limiters. How will you stabilize the
    solution if it becomes unbounded?
•   When using gradient limiters, what is clipping?
•   Use the linearUpwind with different gradient limiters. Which method is more unbounded?
•   Use the vanLeer method with a CFL number of 0.1, 0.9 and 2, did all solutions converge? Are both solutions
    bounded?
•   In the directory tri_mesh, you will find the same case setup using a triangular mesh.
            •   Run the case and compare the solution with the equivalent setup using the orthogonal mesh.
            •   Repeat the same experiments as before and draw your conclusions about which method is better
                for unstructured meshes.
            •   With unstructured meshes, is it possible to get the same accuracy level as for orthogonal meshes?
                                                                                                               724
                               Numerical playground
                                                   Exercises
•   The solver scalarTransportFoam does not report the CFL number on the screen. How will you compute
    the CFL number in this case?
    (Hint: you can take a look at the post-processing slides or the utilities directory)
•   Which one is more diffusive, spatial discretization or time discretization?
•   Are all time discretization schemes bounded?
•   If you are using the Crank-Nicolson scheme, how will you avoid oscillations?
•   Does the solution improve if you reduce the time-step?
•   Use the upwind scheme and a really fine mesh. Does the accuracy of the solution improve?
•   From a numerical point of view, what is the Peclet number? Can it be compared to the Reynolds number?
•   If the Peclet number is more than 2, what will happen with your solution if you were using a linear scheme?
    (Hint: to change the Peclet number you will need to change the diffusion coefficient)
•   Pure convection problems have analytical solutions. You are asked to design your own tutorial with an
    analytical solution in 2D or 3D.
•   Try to break the solver using a time step less than 0.005 seconds. You are allowed to modify the original mesh
    and use any combination of discretization schemes.
                                                                                                                  725
           Numerical playground
Slide:
2D Laplace equation in a square domain.
                                          726
                     Numerical playground
• This is a visual and mental exercise only.
$PTOFC/101FVM/laplace
• In this directory, you will also find the README.FIRST file with the
  instructions of how to run the case.
                                                                         727
  Numerical playground
2D Laplace equation in a square domain
                                         728
                         Numerical playground
                    2D Laplace equation in a square domain
• This case consist of one domain and three different element types.
Domain
• We will study the influence of the element type on the gradients computation.
• We will also study the influence of the gradSchemes method and laplacianSchemes
  method on the solution.
                                                                                 730
      Numerical playground
    2D Laplace equation in a square domain
A              B                           gradSchemes:
                                           Gauss linear
                                           laplacianSchemes:
                                           Gauss linear orthogonal
                                           A. Hexahedral mesh
                                           B. Triangular mesh
                                           C. Polyhedral mesh
                    T field
                                                                                 731
      Numerical playground
    2D Laplace equation in a square domain
A              B                           gradSchemes:
                                           Gauss linear
                                           laplacianSchemes:
                                           Gauss linear orthogonal
                                           A. Hexahedral mesh
                                           B. Triangular mesh
                                           C. Polyhedral mesh
A              B                           gradSchemes:
                                           Gauss linear
                                           laplacianSchemes:
                                           Gauss linear limited 1
                                           A. Hexahedral mesh
                                           B. Triangular mesh
                                           C. Polyhedral mesh
A              B                           gradSchemes:
                                           Gauss leastSquares
                                           laplacianSchemes:
                                           Gauss linear orthogonal
                                           A. Hexahedral mesh
                                           B. Triangular mesh
                                           C. Polyhedral mesh
A              B                           gradSchemes:
                                           Gauss leastSquares
                                           laplacianSchemes:
                                           Gauss linear limited 1
                                           A. Hexahedral mesh
                                           B. Triangular mesh
                                           C. Polyhedral mesh
                                                                                                    736
                               Numerical playground
                                                    Exercises
•   Run the case using all gradient discretization schemes available. Which scheme gives the best results?
•   According to the previous results, which element type is the best one? Do you think that the choice of the
    element type is problem dependent (e.g., direction of the flow)?
•   Use the leastSquares method for gradient discretization, and the corrected and uncorrected method for
    Laplacian discretization. Do you get the same results in all the meshes? How can you improve the results?
    (Hint: look at the corrections)
•   Does it make sense to do more non-orthogonal corrections using the uncorrected method?
•   Run a case only 1 iteration. Do you get a converged solution? Is there a difference between 1 and 100
    iterations? Compare the solutions.
•   Use a different interpolation method for the diffusion coefficient. Do you get the same results?
•   Try to break the solver (this is a difficult task in this case). You are allowed to modify the original mesh and
    use any combination of discretization schemes.
                                                                                                                       737
            Numerical playground
Swing:
Flow in a lid-driven square cavity – Re = 100
Effect of grading and non-orthogonality on the
accuracy of the solution
                                                 738
                              Numerical playground
                       Flow in a lid-driven square cavity – Re = 100
                       Non-orthogonal mesh vs. orthogonal mesh
                                            •    And as CFD is not only about pretty colors, we should also validate
                                                 the results
                          X centerline
High-Re Solutions for incompressible flow using the navier-stokes equations and a multigrid method
U. Ghia, K. N. Ghia, C. T. Shin.
Journal of computational physics, 48, 387-411 (1982)                                                              740
                                         Numerical playground
     LaplacianSchemes orthogonal – Non-orthogonal corrections enabled
       Y centerline
                                            •    And as CFD is not only about pretty colors, we should also validate
                                                 the results
                          X centerline
High-Re Solutions for incompressible flow using the navier-stokes equations and a multigrid method
U. Ghia, K. N. Ghia, C. T. Shin.
Journal of computational physics, 48, 387-411 (1982)                                                              741
                                   Numerical playground
    How to adjust the numerical method to deal with non-orthogonality
ddtSchemes                                                   • In the dictionary fvSchemes we can enable non-
{
    default        backward;                                   orthogonal corrections.
}
                                                             • Non-orthogonal corrections are chosen using the
gradSchemes
{                                                              keywords laplacianSchemes and snGradSchemes.
    default        Gauss linear;
    //default        Gauss skewCorrected linear;             • These are the laplacianSchemes and
    //default        cellMDLimited Gauss linear 1;
    grad(p)        Gauss linear;                               snGradSchemes schemes that you will use most of the
}
                                                               times:
divSchemes
{                                                                 •   orthogonal: second order accurate, bounded on
    default
    //div(phi,U)
                   none;
                     Gauss linearUpwind default;
                                                                      perfect meshes, without non-orthogonal
    div(phi,U)     Gauss linear;                                      corrections.
}
                                                                  •   corrected: second order accurate, bounded
laplacianSchemes
{                                                                     depending on the quality of the mesh, with non-
    default
    //default
                   Gauss linear orthogonal;
                     Gauss linear limited 1;
                                                                      orthogonal corrections.
    //default        Gauss skewCorrected linear limited 1;
}                                                                 •   limited : second order accurate, bounded
interpolationSchemes
                                                                      depending on the quality of the mesh, with non-
{                                                                     orthogonal corrections.
    //default          skewCorrected linear;
    default         linear;                                       •   uncorrected: second order accurate, without
}
                                                                      non-orthogonal corrections. Stable but more
snGradSchemes
{
                                                                      diffusive than limited and corrected.
    default        orthogonal;
    //default        limited 1;
}
                                                                                                                    742
                                    Numerical playground
    How to adjust the numerical method to deal with non-orthogonality
solvers                                    • Additionally, in the dictionary fvSolution we need to
{
    p                                        define the number of PISO corrections (nCorrectors) and
    {                                        non-orthogonal corrections (nNonOrthogonalCorrectors).
          solver         PCG;
          preconditioner DIC;
          tolerance      1e-06;
                                           • You need to do at least one PISO correction. Increasing the
          relTol         0;                  number of PISO correctors will improve the stability and
    }
                                             accuracy of the solution at a higher computational cost.
    pFinal
    {                                      • For orthogonal meshes, 1 PISO correction is ok. But as
         $p;
         relTol          0;                  most of the time you will deal with non-orthogonal meshes,
    }                                        doing 2 PISO corrections is a good choice.
    U
    {                                      • If you are using a method with non-orthogonal corrections
          solver
          smoother
                         smoothSolver;
                         symGaussSeidel;
                                             (corrected or limited 1-0.5), you need to define the number
          tolerance      1e-08;              of non-orthogonal corrections (nNonOrthogonalCorrectors).
          relTol         0;
}
    }
                                           • If you use 0 nNonOrthogonalCorrectors, you are
                                             computing the initial approximation using central differences
PISO
{                                            (accurate but unstable), with no explicit correction.
    nCorrectors     1;
    nNonOrthogonalCorrectors 0;            • To take into account the non-orthogonality of the mesh, you
    pRefCell        0;
    pRefValue       0;                       will need to increase the number of corrections (you get
}                                            better approximations using the previous correction).
                                           • Usually 2 nNonOrthogonalCorrectors is ok.
                                                                                                       743
                               Numerical playground
•    We will now illustrate a few of the discretization schemes available in OpenFOAM®
     using a model case.
•    We will use the lid-driven square cavity case to study the effect of grading and non-
     orthogonality on the accuracy of the solution
•    This case is located in the directory:
$PTOFC/101FVM/nonorthoCavity/
•   In the case directory, you will find the README.FIRST file. In this file, you will find the general instructions of
    how to run the case. In this file, you might also find some additional comments.
•   You will also find a few additional files (or scripts) with the extension .sh, namely, run_all.sh,
    run_mesh.sh, run_sampling.sh, run_solver.sh, and so on. These files can be used to run the case
    automatically by typing in the terminal, for example, sh run_solver.
•   We highly recommend you to open the README.FIRST file and type the commands in the terminal, in this
    way, you will get used with the command line interface and OpenFOAM® commands.
•   If you are already comfortable with OpenFOAM®, use the automatic scripts to run the cases.
                                                                                                                      744
                              Numerical playground
                                        What are we going to do?
•   This is the same case as the one we used during the first tutorial session.
•   The only difference is that we have modified the mesh a little bit in order to add grading and non-orthogonality.
•   After generating the mesh, we will use the utility checkMesh to control the quality of the mesh. Is it a good
    mesh?
•   We will use this case to learn how to adjust the numerical schemes according to mesh non-orthogonality and
    grading.
•   After finding the numerical solution we will do some sampling and plotting.
    1.     $> foamCleanTutorials
    2.     $> blockMesh –dict system/blockMeshDict.0
    3.     $> checkMesh
    4.     $> pisoFoam | log.solver
    5.     $> postProcess -func sampleDict -latestTime
    6.     $> gnuplot gnuplot/gnuplot_script
    7.     $> paraFoam
                                                                                                                   745
                            Numerical playground
                             To run the case, follow these steps
•   First run the case using the original dictionaries. Did it crash right?
•   Now change the laplacianSchemes and snGradSchemes to limited 1. It crashed again but
    this time it ran a few more time-steps, right?
•   Now increase the number of nNonOrthogonalCorrectors to 2. It crashed again but it is running
    more time-steps, right?
•   Now increase the number of PISO corrections to 2 (nCorrectors). Did it run?
•   Basically we enabled non-orthogonal corrections, we computed better approximations of the
    gradients, and we increased the number of PISO corrections to get better predictions of the field
    variables (U and p).
•   Now set the number of nNonOrthogonalCorrectors to 0. Did it crash right? This is telling us
    that the mesh is sensitive to the gradients.
•   Now change the laplacianSchemes and snGradSchemes to limited 0 (uncorrected). In this
    case we are not using non-orthogonal corrections, therefore there is no need to increase the
    value of nNonOrthogonalCorrectors.
•   We are using a method that uses a wider stencil to compute the Laplacian, this method is more
    stable but a little bit more diffusive. Did it run?
•   At this point, compare the solution obtained with corrected and uncorrected schemes. Which
    one is more diffusive?
                                                                                                   746
                            Numerical playground
•   When it comes to laplacianSchemes and snGradSchemes this is how we proceed most of
    the times (a robust setup),
        laplacianSchemes
        {
               default   Gauss linear limited 1;            PISO
        }                                                   {
                                                                   nCorrectors 2;
        snGradSchemes                                              nNonOrthogonalCorrectors 1;
        {                                                   }
             default  limited 1;
        }
•   This method works fine for meshes with non-orthogonality less than 75.
•   If the non-orthogonality is more than 75, you should consider using limited 0.5, and increasing
    nCorrectors and nNonOrthogonalCorrectors.
•   When the non-orthogonality is more than 85, the best solution is to redo the mesh.
                                                                                                  747
                              Numerical playground
                                                  Exercises
•   Using the non-orthogonal mesh and the original dictionaries, try to run the solver reducing the time-step. Do
    you get a solution at all?
•   Try to get a solution using the method limited 1 and two nNonOrthogonalCorrectors (leave nCorrectors
    equal to 1).
    (Hint: try to reduce the time-step)
•   If you managed to get a solution using the previous numerical scheme. How long did it take to get the
    solution? Use the robust setup, clock the time and compare with the previous case. Which one is faster? Do
    you get the same solution?
•   Instead of using the non-orthogonal mesh, use a mesh with grading toward all edges. How will you stabilize
    the solution?
    (Hint: take a look at the blockMesh slides in order to add grading to the mesh)
•   Try to get a solution using a time-step of 0.05 seconds. Use the original discretization schemes for the gradient
    and convective terms.
    (Hint: increase nCorrectors and nNonOrthogonalCorrectors)
•   Using the uniform orthogonal mesh and a robust numerics, determined the largest CFL you can use. Is the
    solution still accurate? What about the clock-speed?
•   Try to break the solver and interpret the output screen. You are allowed to modify the original mesh and use
    any combination of discretization schemes.
                                                                                                                   748
           Numerical playground
Seesaw:
Sod’s shock tube.
                                  749
                           Numerical playground
                                       Sod’s shock tube
•   This case has an analytical solution and plenty of experimental data.
•   This is an extreme test case used to test solvers.
•   Every single commercial and open source solver use this case for validation of the numerical
    schemes.
•   The governing equation of this test case are the Euler equations.
                                                                                                   750
                                  Numerical playground
                       High Purity Photolysis Shock Tube (NASA Tube)
Shock tube. The driver section, including vacuum pumps, controls, and helium driver gas.
Photo credit: Stanford University. http://hanson.stanford.edu/index.php?loc=facilities_nasa
Copyright on the images is held by the contributors. Apart from Fair Use, permission must be sought for any other purpose.   751
                        Numerical playground
                                      Sod’s shock tube
                                                                               752
            Numerical playground
                           Sod’s shock tube
$PTOFC/101FVM/shockTube/
•   In the case directory, you will find the README.FIRST file. In this file, you will find the general instructions of
    how to run the case. In this file, you might also find some additional comments.
•   You will also find a few additional files (or scripts) with the extension .sh, namely, run_all.sh,
    run_mesh.sh, run_sampling.sh, run_solver.sh, and so on. These files can be used to run the case
    automatically by typing in the terminal, for example, sh run_solver.
•   We highly recommend you to open the README.FIRST file and type the commands in the terminal, in this
    way, you will get used with the command line interface and OpenFOAM® commands.
•   If you are already comfortable with OpenFOAM®, use the automatic scripts to run the cases.
                                                                                                                      754
                            Numerical playground
                                   What are we going to do?
•   Now is your turn.
•   You are asked to select the best discretization scheme for the physics involve.
•   Remember the following concepts: accuracy, stability and boundedness.
•   We will compare your numerical solution with the analytical solution.
•   At this point, we are very familiar with the numerical schemes. It is up to you to choose the best
    setup.
•   You can start using the original dictionaries.
•   To find the numerical solution we will use the solver rhoPimpleFoam.
•   rhoPimpleFoam is a transient solver for laminar or turbulent flow of a compressible gas.
•   After finding the numerical solution we will do some sampling.
•   At the end, we will do some plotting (using gnuplot or Python) and scientific visualization.
                                                                                                    755
                                   Numerical playground
                                                    Running the case
•   You will find this tutorial in the directory $PTOFC/101FVM/schockTube
•   In the terminal window type:
    1.      $> foamCleanTutorials
    2.      $> blockMesh
    3.      $> checkMesh
    4.      $> rm –rf 0
    5.      $> cp –r 0_org 0
    6.      $> setFields
    7.      $> rhoPimpleFoam | tee log.solver
    8.      $> postProcess -func sampleDict -latestTime
    9.      $> paraFoam
•   To plot the analytical solution against the numerical solution, go to the directory python and run the Python script.
•   In the terminal window type:
•   The Python script will save four .png files with the solution. Feel free to explore and adapt the Python script to your needs.
•   Python (version 3) must be installed in order to use the script
                                                                                                                                     756
                               Numerical playground
                                             Running the case
•   If you used the values proposed in the dictionaries, the solution diverged, right? Try to get the
    case working.
    Hint: look at the gradient limiters.
•   By adjusting the gradient limiters, the case will run, but the final solution is not very accurate.
    How can you increase the accuracy of the solution?
    Hint: look at the PIMPLE corrections.
                                                                                                          757
                              Numerical playground
                                                  Exercises
•   Using the proposed case setup, try to get an accurate solution by reducing the time-step or refining the mesh.
    Did you succeed in getting an accurate solution?
•   Run the case using different time discretization schemes.
•   Run the case using different gradient discretization schemes.
•   Run the case using different convective discretization schemes for the term div(phi,U).
•   Run the case using different convective discretization schemes for the terms div(phi,e) and div(phi,K). What
    are the variables e and K?
•   Extend the case to 2D and 3D. Do you get the same solution?
•   Try to run a 2D case using a triangular mesh and adjust the numerical scheme to get an accurate and stable
    solution.
•   Try to run the 1D case using an explicit solver. For the same CFL number, do you have the same time step
    size as for the implicit solver?
    (Hint: look for the solver with the word Central)
•   Try to break the solver (this is extremely easy in this case). You are allowed to modify the original mesh and
    use any combination of discretization schemes.
                                                                                                                 758
          Module 7
 Highlights – Implementing boundary
conditions and initial conditions using
             codeStream
                                          759
                     Roadmap
1. codeStream – Highlights
2. Implementing boundary conditions using
   codeStream
3. Solution initialization using codeStream
                                              760
                            codeStream – Highlights
                           codeStream – Boundary conditions
•   There are many boundary conditions available in OpenFOAM®.
•   But from time to time it may happen that you do not find what you are looking for.
•   It is possible to implement your own boundary conditions, so in theory you can do whatever you
    want.
•   Remember, you have the source code.
•   To implement your own boundary conditions, you have three options:
           •   Use codeStream.
           •   Use high level programing.
           •   Use an external library (e.g., swak4foam).
•   codeStream is the simplest way to implement boundary conditions, and most of the times you
    will be able to code boundary conditions with no problem.
•   If you can not implement your boundary conditions using codeStream, you can use high level
    programming. However, this requires some knowledge on C++ and OpenFOAM® API.
•   Hereafter, we are going to work with codeStream and basic high-level programming.
•   We are not going to work with swak4Foam because it is an external library that is not officially
    supported by the OpenFOAM® foundation. However, it works very well and is relatively easy to
    use.                                                                                             761
                             codeStream – Highlights
                               codeStream – Initial conditions
•   When it comes to initial conditions, you can use the utility setFields.
•   This utility is very flexible, you can even read STL files and use them to initialize fields.
•   But again, it may happen that you can not get the desired results.
•   As for boundary conditions, to implement your own initials conditions you have three options:
           •   Use codeStream.
           •   Use high level programing.
           •   Use an external library (e.g., swak4foam).
•   codeStream is the simplest way to implement initial conditions, and most of the times you will
    be able to code initial conditions with no problem.
•   If you can not implement your initial conditions using codeStream, you can use high level
    programming. However, this requires some knowledge on C++ and OpenFOAM® API.
•   Hereafter, we are going to work only with codeStream.
•   Using high level programming is a little bit trickier, and we guarantee you that 99.9% of the times
    codeStream will work.
•   We are not going to work with swak4Foam because it is an external library that is not officially
    supported by the OpenFOAM® foundation. However, it works very well and is relatively easy to
    use.                                                                                             762
                            codeStream – Highlights
•   Hereafter we will work with codeStream, which will let us program directly in the input
    dictionaries.
•   With codeStream, we will implement our own boundary conditions and initial conditions without
    going thru the hustle and bustle of high-level programming.
•   If you are interested in high level programming, refer to the supplements.
•   In the supplemental slides, we address the following topics:
           •   Building blocks, implementing boundary conditions using high level programming,
               modifying applications, implementing an application from scratch, and adding the
               scalar transport equation to icoFoam.
•   High level programming requires some knowledge on C++ and OpenFOAM® API library.
•   This is the hard part of programming in OpenFOAM®.
•   Before doing high level programming, we highly recommend you try with codeStream, most of
    the time it will work.
•   Also, before modifying solvers or trying to implement your own solvers, understand the theory
    behind the FVM.
•   Remember, you can access the API documentation in the following link,
    https://cpp.openfoam.org/v8
                                                                                                    763
                     Roadmap
1. codeStream – Highlights
2. Implementing boundary conditions using
   codeStream
3. Solution initialization using codeStream
                                              764
       Implementing boundary conditions using codeStream
•   OpenFOAM® includes the capability to compile, load and execute C++ code at run-time.
•   This capability is supported via the directive #codeStream, that can be used in any input file for
    run-time compilation.
•   This directive reads the entries code (compulsory), codeInclude (optional), codeOptions
    (optional), and codeLibs (optional), and uses them to generate the dynamic code.
•   The source code and binaries are automatically generated and copied in the directory
    dynamicCode of the current case.
•   The source code is compiled automatically at run-time.
•   The use of codeStream is a very good alternative to avoid high level programming of boundary
    conditions or the use of external libraries.
•   Hereafter we will use codeStream to implement new boundary conditions.
•   Have in mind that codeStream can be used in any dictionary.
                                                                                                    765
    Implementing boundary conditions using codeStream
         Body of the codeStream directive for boundary conditions
patch-name                                           Patch name
{
    type             fixedValue;
    value            #codeStream
                                                     Use codeStream to set the value
    {                                                of the boundary condition
         codeInclude
         #{
             #include "fvCFD.H"                      Files needed for compilation
         #};
         codeOptions
         #{
             -I$(LIB_SRC)/finiteVolume/lnInclude \   Compilation options
             -I$(LIB_SRC)/meshTools/lnInclude
         #};
         code
         #{                                          Insert your code here.
                                                     At this point, you need to know
         #};                                         how to access mesh information
    };
}
                                                                                       766
          Implementing boundary conditions using codeStream
              Implementation of a parabolic inlet profile using codeStream
•   Let us implement a parabolic inlet profile.
•   The firs step is identifying the patch, its location and the dimensions.
•   You can use paraview to get all visual references.
                                    Outlet
                                    pressure-outlet-7
Inlet
velocity-inlet-5
                                     Inlet
                                     velocity-inlet-6          Bounds of velocity-inlet-5 boundary patch
          Parabolic inlet profile                                                                          767
       Implementing boundary conditions using codeStream
          Implementation of a parabolic inlet profile using codeStream
•   We will use the following formula to implement the parabolic inlet profile
•   For this specific case c is the patch midpoint in the y direction (8), r is the patch semi-height or
    radius (8) and Umax is the maximum velocity.
•   We should get a parabolic profile similar to this one,
                                                                                                           768
        Implementing boundary conditions using codeStream
•   The codeStream BC in the body of the file U is as follows,
             code
             #{                                                  Insert your code here.
                                                                 At this point, you need to know
             #};                                                 how to access mesh information
        };
    }
                                                                                                   769
       Implementing boundary conditions using codeStream
•   The code section of the codeStream BC in the body of the file U is as follows,
•   Lines 3-11, are always standard, they are used to access boundary mesh information.
•   In lines 3-6 we access the current dictionary.
•   In line 8 we access the mesh database.
•   In line 9 we get the label id (an integer) of the patch velocity-inlet-5 (notice that you need to give the name of
    the patch).
•   In line 10 using the label id of the patch, we access the boundary mesh information.
•   In line 12 we initialize the vector field. The statement patch.size() gets the number of faces in the patch, and
    the statement vector(0, 0, 0) initializes a zero-vector field in the patch.                                     770
       Implementing boundary conditions using codeStream
•   The code section of the codeStream BC in the body of the file U is as follows,
     1.     $> foamCleanTutorials
     2.     $> fluentMeshToFoam ../../../meshes_and_geometries/fluent_elbow2d_1/ascii.msh
     3      $> checkMesh
     4.     $> rm –rf 0
     5.     $> cp –r 0_org 0
     6.     $> pisoFoam | tee log.solver
     7.     $> paraFoam
                                                                         773
          Implementing boundary conditions using codeStream
                       codeStream works with scalar and vector fields
•     We just implemented the input parabolic profile using a vector field.
•     You can do the same using a scalar field, just proceed in a similar way.
•     Remember, now we need to use scalars instead of vectors.
•     And you will also use an input dictionary holding a scalar field.
           1     code
           2     #{
           3         ...
           4         ...
           5         ...
           6          scalarField S(patch.size(), scalar(0) );                         Initialize scalar field
           7
           8           forAll(S, i)                    Loop using scalar field size
           9           {
           10              const scalar y = patch.Cf()[i][1];
           11              S[i] = scalar( 2.0*sin(3.14159*y/8.) );
                                                                                    Write profile values
           12          }                                                            in scalar field
           13
           14          writeEntry(os, "", S);
                                                                                       Write output to input
           15    #};                                                                   dictionary
    Notice that the name of the field does not need to be the same as the name of the input dictionary
                                                                                                                 774
            Implementing boundary conditions using codeStream
             Implementation of a paraboloid inlet profile using codeStream
•     Let us work in a case a little bit more complicated, a paraboloid input profile.
•     As usual, the first step is to get all the spatial references.
    Inlet
    auto3
                                                                            776
        Implementing boundary conditions using codeStream
•   The codeStream BC in the body of the file U is as follows,
             codeLibs
             #{
                 -lmeshTools \
                 -lfiniteVolume
             #};
                                                                 Insert your code here.
             code
             #{
                                                                 We will implement the following
                                                                 equation
             #};
        };
    }
                                                                                                   777
       Implementing boundary conditions using codeStream
•   Hereafter, we only show the actual implementation of the codeStream boundary condition.
•   The rest of the body is a template that you can always reuse. Including the section of how to
    access the dictionary and mesh information.
•   Remember, is you are working with a vector, you need to use vector fields. Whereas, if you are
    working with scalars, you need to use scalars fields.
       1    code
       2    #{
       3        ...
       4        ...
       5        ...
       6         vectorField U(patch.size(), vector(0, 0, 0) );
       7
       8          const scalar s   = 0.5;                                             Initialize vector field
       9
       10         forAll(U,   i)                             Initialize scalar
       11         {
       12             const   scalar x = patch.Cf()[i][0];
                                                                                 Access faces center
       13             const   scalar y = patch.Cf()[i][1];
       14             const   scalar z = patch.Cf()[i][2];                       coordinates (x, y, and z)
       15
       16             U[i] = vector(-1.*(pow(z/s, 2) + pow((y-s)/s,2) - 1.0), 0, 0);
       17         }
       18
       19         writeEntry(os, "", U);
       20   #};
                                                                                                                778
       Implementing boundary conditions using codeStream
          Implementation of a paraboloid inlet profile using codeStream
•   This case is ready to run, the input files are located in the directory
    $PTOFC/101programming/codeStream_BC/3Delbow_Uparaboloid/
•   To run the case, type in the terminal,
     1.     $> foamCleanTutorials
     2.     $> gmshToFoam ../../../meshes_and_geometries/gmsh_elbow3d/geo.msh
                                                                         780
       Implementing boundary conditions using codeStream
             codedFixedValue and codedMixed boundary conditions
•   OpenFOAM® also includes the boundary conditions codedFixedValue and codedMixed.
•   These boundary conditions are derived from codeStream and work in a similar way.
•   They use a friendlier notation and let you access more information of the simulation database
    (e.g. time).
•   The source code and binaries are automatically generated and copied in the directory
    dynamicCode of the current case.
•   Another feature of these boundary conditions, is that the code section can be read from an
    external dictionary (system/codeDict), which is run-time modifiable.
•   The boundary condition codedMixed works in similar way. This boundary condition gives you
    access to fixed values (Dirichlet BC) and gradients (Neumann BC).
•   Let us implement the parabolic profile using codedFixedValue.
                                                                                                    781
     Implementing boundary conditions using codeStream
               Body of the codedFixedValue boundary conditions
patch-name                                         Patch name
{
    type              codedFixedValue;             Use codedFixedValue and
    value             uniform (0 0 0);             initializations
                                                   Unique name of the new boundary
     name    name_of_BC;                           condition.
                                                   If you have more codedFixedValue
/*                                                 BC, the names must be different
     codeOptions
     #{
         -I$(LIB_SRC)/finiteVolume/lnInclude \
         -I$(LIB_SRC)/meshTools/lnInclude          Optional compilation options.
     #};                                           You do not need to add these options
                                                   unless it is required.
     codeInclude                                   At the following link, you can find a bug
     #{                                            related to codedFixedValue (SEP2020)
         #include "fvCFD.H"                        https://bugs.openfoam.org/view.php?id=3555
         #include <cmath>
         #include <iostream>
     #};
                                                   In this section we do the actual
*/
                                                   implementation of the boundary
     code                                          condition.
     #{                                            This is the only part of the body
                                                   that you will need to change. The
     #};                                           rest of the body is a template that
}
                                                   you can always reuse.             782
         Implementing boundary conditions using codeStream
•   The code section of the codeStream BC in the body of the file U is as follows,
    1     code
    2     #{
    3            const fvPatch& boundaryPatch = patch();
    4            const vectorField& Cf = boundaryPatch.Cf();
    5            vectorField& field = *this;
    6
    7            scalar U_0 = 2, p_ctr = 8, p_r = 8;
    8
    9            forAll(Cf, faceI)
    10           {
    11               field[faceI] = vector(U_0*(1-(pow(Cf[faceI].y()-p_ctr,2))/(p_r*p_r)),0,0);
    12           }
    13     #};
•   Lines 3-5, are always standard, they give us access to mesh and field information in the patch.
•   The coordinates of the faces center are stored in the vector field Cf (line 4).
•   In this case, as we are going to implement a vector profile, we initialize a vector field where we are going to
    assign the profile (line 5).
•   In line 7 we initialize a few constants that will be used in our implementation.
•   In lines 9-12 we use a forAll loop to access the boundary patch face centers and to assign the velocity profile
    values.
•   In line 11 we do the actual implementation of the boundary profile (similar to the codeStream case). The
    vector field was initialized in line 5.
                                                                                                                  783
       Implementing boundary conditions using codeStream
             codedFixedValue and codedMixed boundary conditions
•   As you can see, the syntax and use of the codedFixedValue and codedMixed boundary
    conditions is much simpler than codeStream.
•   You can use these instructions as a template.
•   At the end of the day, you only need to modify the code section.
•   Depending of what you want to do, you might need to add new headers and compilation options.
•   Remember, is you are working with a vector, you need to use vector fields. Whereas, if you are
    working with scalars, you need to use scalars fields.
•   One disadvantage of these boundary conditions, is that you can not visualize the fields at time
    zero. You will need to run the simulation for at least one iteration.
•   On the positive side, accessing time and other values from the simulation database is
    straightforward.
•   Time can be accessed by adding the following statement,
this->db().time().value()
                                                                                                      784
         Implementing boundary conditions using codeStream
•    Let us add time dependency to the parabolic profile.
    1    code
    2    #{
    3           const fvPatch& boundaryPatch = patch();
    4           const vectorField& Cf = boundaryPatch.Cf();
    5           vectorField& field = *this;
    6
    7           scalar U_0 = 2, p_ctr = 8, p_r = 8;
    8
    9           scalar t = this->db().time().value();                  Time
    10
    11          forAll(Cf, faceI)
    12          {
    13             field[faceI] = vector(sin(t)*U_0*(1-(pow(Cf[faceI].y()-p_ctr,2))/(p_r*p_r))),0,0);
    14          }
    15    #};
                                                Time dependency
•    This implementation is similar to the previous one, we will only address how to deal with time.
•    In line 8 we access simulation time.
•    In line 13 we do the actual implementation of the boundary profile (similar to the codeStream
     case). The vector field was initialized in line 5 and time is accessed in line 9.
•    In this case, we added time dependency by simple multiplying the parabolic profile by the
     function sin(t).
                                                                                                       785
       Implementing boundary conditions using codeStream
      Implementation of a parabolic inlet profile using codedFixedValue
•   This case is ready to run, the input files are located in the directory
    $PTOFC/101programming/codeStream_BC/2Delbow_UparabolicInlet_timeDep
•   To run the case, type in the terminal,
     1.     $> foamCleanTutorials
     2.     $> fluentMeshToFoam ../../../meshes_and_geometries/fluent_elbow2d_1/ascii.msh
                                                                                            786
       Implementing boundary conditions using codeStream
      Implementation of a parabolic inlet profile using codedFixedValue
•   If everything went fine, you should get something like this,
www.wolfdynamics.com/wiki/BCIC/elbow_unsBC1.gif
                                                                                 787
        Implementing boundary conditions using codeStream
                               Filling a tank using codedFixedValue
•   Let us do a final example.
                                                                  Water enters here
•   We will deal with scalar and vector fields at the same        This is a face selection in a single boundary patch
    time.
•   We will use codedFixedValue.
•   For simplicity, we will only show the code section of the
    input files.
•   Remember, the rest of the body can be used as a
    template.
•   And depending of what you want to do, you might need
    to add new headers, libraries, and compilation options.
•   Hereafter we will setup an inlet boundary condition in a
    portion of an existing patch.
•   By using codedFixedValue BC, we do not need to
    modify the actual mesh topology.
•   We will assign a velocity field and a scalar field to a set
    of faces (dark area in the figure).
•   We are going to simulate filling a tank with water.
•   We will use the solver interFoam.                                       The tank is initially empty
                                                                                                                        788
         Implementing boundary conditions using codeStream
•   Definition of the vector field boundary condition (dictionary file U),
                                                                                                              789
         Implementing boundary conditions using codeStream
•   Definition of the vector field boundary condition (dictionary file U),
    7     code                        Code section. The actual implementation of the BC is done in this section
    8     #{
                 ...
                 ...                                          Loop using size of boundary patch (Cf) and iterator
                 ...                                          faceI.
    19                                                        This is equivalent to:
    20           forAll(Cf, faceI)                              for (int faceI=0; Cf.size()<faceI; faceI++)
    21           {
    22
    23                 if (
    24                        (Cf[faceI].z()   >   minz) &&
                                                                                  Use conditional structure to
    25                        (Cf[faceI].z()   <   maxz) &&
    26                        (Cf[faceI].y()   >   miny) &&                       select faces according to the
    27                        (Cf[faceI].y()   <   maxy)                          variables defined in lines 13-16
    28                   )
    29                   {
    30                         if ( t < 1.)
    31                         {                                                       Use conditional structure to
    32                              field[faceI] = vector(1,0,0);                      add time dependency and
    33                         }                                                       assign values to the
    34                         else
                                                                                       selected faces.
    35                         {
    36                              field[faceI] = vector(0,0,0);                      The variable field was
    37                         }                                                       initialize in line 11.
    38                   }
    39           }
    40     #};
    41     }
                                                                                                                      790
         Implementing boundary conditions using codeStream
•   Definition of the scalar field boundary condition (dictionary file alpha.water),
    7         code               Code section. The actual implementation of the BC is done in this section
    8         #{
                     ...
                                                       Loop using size of boundary patch (Cf) and iterator
                     ...
                     ...                               faceI.
    22                                                 This is equivalent to:
    23               forAll(Cf, faceI)                   for (int faceI=0; Cf.size()<faceI; faceI++)
    24               {
    25                   if (
    26                         (Cf[faceI].z() > minz) &&                   Use conditional structure to
    27                         (Cf[faceI].z() < maxz) &&                   select faces according to the
    28                         (Cf[faceI].y() > miny) &&
                                                                           variables defined in lines 13-16
    29                         (Cf[faceI].y() < maxy)
    30                      )
    31                      {
    32                          if ( t < 1.)
    33                          {                                          Use conditional structure to add
    34                               field[faceI] = 1.;                    time dependency and assign
    35                          }
    36                          else
                                                                           values to the selected faces.
    37                          {                                          The variable field was initialize in
    38                               field[faceI] = 0.;                    line 11.
    39                          }
    40                      }
    41                }
    42         #};
    43    }
                                                                                                              792
       Implementing boundary conditions using codeStream
      Implementation of a parabolic inlet profile using codedFixedValue
•   This case is ready to run, the input files are located in the directory
    $PTOFC/101programming/codeStream_BC/fillBox_BC/
•   To run the case, type in the terminal,
      1.    $> foamCleanTutorials
      2.    $> blockMesh
      3.    $> rm –rf 0
      4.    $> cp –r 0_org 0
      5.    $> decomposePar
      6.    $> mpirun -np 4 interFoam -parallel | tee log.solver
      7.    $> reconstructPar
      8.    $> paraFoam
00
00
00
0 02
0 01
                                                             0
                                                                 0   02   0   0   0   1   12   1   1   1   2
1. codeStream – Highlights
2. Implementing boundary conditions using
   codeStream
3. Solution initialization using codeStream
                                              795
                   Solution initialization using codeStream
•   When it comes to initial conditions, you can use the utility setFields.
•   This utility is very flexible, you can even read STL files and use them to initialize your fields.
•   But in case that you can not get the desired results using setFields, you can implement your
    own initial conditions using codeStream.
•   To implement initial conditions using codeStream, we proceed in a similar way as for boundary
    conditions.
•   The source code and binaries are automatically generated and copied in the directory
    dynamicCode of the current case.
•   The source code is compiled automatically at run-time.
•   The use of codeStream is a very good alternative to avoid high level programming of initial
    conditions or the use of external libraries.
•   Hereafter we will use codeStream to implement new initial conditions.
                                                                                                         796
                                     Solution initialization using codeStream
                                Body of the codeStream directive for initial conditions
internalField   #codeStream                                               Use codeStream to set the value
{                                                                         of the initial conditions
    {
        codeInclude
        #{
            #include "fvCFD.H"                                            Files needed for compilation
    Initial conditions
#};
                              codeOptions
                              #{
                                  -I$(LIB_SRC)/finiteVolume/lnInclude \   Compilation options
                                  -I$(LIB_SRC)/meshTools/lnInclude
                              #};
                              codeLibs
                                                                          Libraries needed for compilation.
                              #{
                                  -lmeshTools \                           Needed if you want to visualize the
                                  -lfiniteVolume                          output of the initial conditions at
                              #};                                         time zero
                              code
                              #{
                                                                          Insert your code here.
                              #};                                         At this point, you need to know
                         };                                               how to access internal mesh
}                                                                         information
                                                                                                            797
                   Solution initialization using codeStream
          Implementation of an elliptic initialization using codeStream
•   Let us implement an elliptic initialization using codeStream.
•   The firs step is to know your domain and identify the region that you want to initialize.
•   Then you will need to do a little bit of math to get the expression for the initialization.
•   In this example, we are also going to show you how to do the same initialization by reading a
    STL file with the utility setFields.
Phase 1
                                                                                                                        798
                  Solution initialization using codeStream
• The codeStream IC in the body of the file alpha.phase1 is as follows,
           code
           #{
                                                          Insert your code here.
           #};                                            At this point, you need to know
      };                                                  how to access internal mesh
  }                                                       information
                                                                                            799
                                        Solution initialization using codeStream
•                       The code section of the codeStream IC in the body of the file alpha.phase1 is as follows,
                                                                                                                                   following statement
                                   }
                                                                                                                                                      800
                   Solution initialization using codeStream
              Implementation of an elliptic initialization using codeStream
•   This case is ready to run, the input files are located in the directory
    $PTOFC/101programming/codeStream_INIT/elliptical_IC
•   To run the case, type in the terminal,
     1.     $> foamCleanTutorials
     2.     $> blockMesh
     3.     $> rm –rf 0
     4.     $> cp –r 0_org 0
     5.     $> paraFoam
     6.     $> interFoam | tee log.solver
     7.     $> paraFoam
                                                                              801
                       Solution initialization using codeStream
                 Implementation of an elliptic initialization using codeStream
Surface tension driven flow - Bubble in a zero gravity flow using interFoam
                                                                                                                           802
                   Solution initialization using codeStream
                            Elliptic initialization using setFields
•   Let us do the same initialization using a STL file with setFields.
•   First, you will need to create the solid model that encloses the region you want to initialize.
•   For this, you can use your favorite CAD/solid modeling software. Remember to save the
    geometry is STL format.
•   Then you will need to read in the STL file using setFields.
•   You will need to modify the setFieldsDict dictionary.
                                                                                      Region defined by
                                                                                      the STL file
    Computational domain
                                                                                                          803
                Solution initialization using codeStream
                                  The setFieldsDict dictionary
defaultFieldValues
(
    volScalarFieldValue alpha.phase1 0                     Initialize the whole domain to zero
);
regions
                                                          setFields method to read STL files.
(                                                         If you want to know all the options
                                                          available use a word that does not exist
     surfaceToCell                                        in the enumerator list (e.g. banana)
     {
         file "./geo/ellipse.stl";                         Location of the STL file to read
          outsidePoints ((0.5 0.85 0));                    A point located outside the STL
      1.    $> foamCleanTutorials
      2.    $> blockMesh
      3.    $> rm –rf 0
      4.    $> cp –r 0_org 0
      5.    $> setFields
      6.    $> paraFoam
                                                                              805
                   Solution initialization using codeStream
                         Rayleigh-Taylor instability initialization
                                                                      806
                                     Solution initialization using codeStream
•        The code section of the codeStream IC in the body of the file alpha.phase1 is as follows,
                            {
                                const scalar x = mesh.C()[i][0];
                                const scalar y = mesh.C()[i][1];
                                                                                      Access cell centers coordinates
                                if (y >= -0.05*cos(2*constant::mathematical::pi*x))
                                {
                                    alpha[i] = 1.;
                                }
                            }
                                                                                                                                  807
                       Solution initialization using codeStream
                             Rayleigh-Taylor instability initialization
•       This case is ready to run, the input files are located in the directory
        $PTOFC/101programming/codeStream_INIT/rayleigh_taylor
•       To run the case, type in the terminal,
        1.    $> foamCleanTutorials
        2.    $> blockMesh
        3.    $> rm –rf 0
        4.    $> cp –r 0_org 0
        5.    $> interFoam | tee log.solver
        6.    $> paraFoam
                                                                                  808
                   Solution initialization using codeStream
                            Rayleigh-Taylor instability initialization
•   If everything went fine, you should get something like this,
                                                                                                           809
                     Solution initialization using codeStream
                Filling a tank using codeStream and codedFixedValue
•   Let us do a final example.
•   We will implement BCs and ICs at the same.
•   For simplicity, we will only show the code section of the input files.
•   This setup is similar to the last example of the previous section (filling a tank using
    codedFixedValue).
                                                                                                           810
                    Solution initialization using codeStream
•   The code section of the codeStream IC in the body of the file alpha.water is as follows,
    internalField    #codeStream
                                                      Use codeStream to set the
    {                                              value of the initial conditions
                  if (y <= 0.2)
                  {                                    Assign value to alpha according to
                      alpha[i] = 1.;                   conditional structure
                  }
              }
                                                                                                                                         811
                    Solution initialization using codeStream
•   The code section of the codeFixedValue BC in the body of the file U is as follows,
                                                                                                                              812
                        Solution initialization using codeStream
•   The code section of the codeFixedValue BC in the body of the file U is as follows,
                 if (
                        (Cf[faceI].z()   >   min) &&
                        (Cf[faceI].z()   <   max) &&                              Use conditional structure to
                        (Cf[faceI].y()   >   min) &&                              select faces.
                        (Cf[faceI].y()   <   max)
                    )
                    {
                        if ( t < 2.)
                        {
                             field[faceI] = vector(1,0,0);                            Use conditional structure to
                        }                                                             add time dependency and
                        else
                                                                                      assign values to the
                        {
                             field[faceI] = vector(0,0,0);                            selected faces.
                        }
                    }
           }
    #};
                                                                                                                     813
                    Solution initialization using codeStream
•   The code section of the codeFixedValue BC in the body of the file alpha.water is as follows,
field = patchInternalField(); Assign value from the internal field to the patch
                                                                                                       815
                   Solution initialization using codeStream
              Filling a tank using codeStream and codedFixedValue
•   If everything went fine, you should get something like this,
02
02
02
0 22
02
                                                                   01
                                                                          0   0   1   1   2   2
                                                                                                       816
           Module 8
           Advanced physics
Turbulence modeling – Multiphase flows –
 Compressible flows – Moving bodies –
     Source terms – Passive scalars
                                           817
• In this module, we will deal with advanced modeling capabilities.
• Advanced modeling capabilities rely a lot in physical models, such as,
  turbulence, multiphase flows, porous media, combustion, radiation, heat
  transfer, phase change, acoustics, cavitation, and so on.
• Therefore, it is extremely important to get familiar with the theory behind
  these models.
                                          819
 A crash introduction to turbulence modeling in OpenFOAM®
                                            What is turbulence?
Wake turbulence behind individual wind turbines                             Flow visualization over a spinning spheroid
Photo credit: NREL's wind energy research group.                            Photo credit: Y. Kohama.
Copyright on the images is held by the contributors. Apart from Fair Use,   Copyright on the images is held by the contributors. Apart from Fair Use,
permission must be sought for any other purpose.                            permission must be sought for any other purpose.
Von Karman vortices created when prevailing winds sweeping east across      Vortices on a 1/48-scale model of an F/A-18 aircraft inside a Water
the northern Pacific Ocean encountered Alaska's Aleutian Islands            Tunnel
Photo credit: USGS EROS Data Center Satellite Systems Branch.               Photo credit: NASA Dryden Flow Visualization Facility.
Copyright on the images is held by the contributors. Apart from Fair Use,   Copyright on the images is held by the contributors. Apart from Fair Use,
permission must be sought for any other purpose.                            permission must be sought for any other purpose.                        821
 A crash introduction to turbulence modeling in OpenFOAM®
                                                                                                                     Abstract representation of
                                                                                                                      the drag decomposition
Flow around two spheres. Left image: smooth sphere. Right image: sphere with rough surface at the nose
Photo credit: http://www.mhhe.com/engcs/civil/finnemore/graphics/photos/AuthorRecommendedImages/index.html
Copyright on the images is held by the contributors. Apart from Fair Use, permission must be sought for any other purpose                    822
A crash introduction to turbulence modeling in OpenFOAM®
                                                                                                                                 823
A crash introduction to turbulence modeling in OpenFOAM®
 URANS (K-Omega SST with no wall functions) –                           LES (Smagorinsky) – Vortices visualized by Q-criterion
      Vortices visualized by Q-criterion                                             www.wolfdynamics.com/wiki/squarecil/les.gif
          www.wolfdynamics.com/wiki/squarecil/urans2.gif
References:
Lyn, D.A. and Rodi, W., The flapping shear layer formed by flow separation from the forward corner of a square cylinder. J. Fluid Mech., 267, 353, 1994.
Lyn, D.A., Einav, S., Rodi, W. and Park, J.H., A laser-Doppler velocimetry study of ensemble-averaged characteristics of the turbulent near wake of a square
cylinder. Report. SFB 210 /E/100.
                                                                                                                                                               825
 A crash introduction to turbulence modeling in OpenFOAM®
Inflow
                                                                                                                      Turbulence model 1
                                                                                                                      Turbulence model 2
                                                                                                                      Turbulence model 3
                                                                                                                      Turbulence model 4
                                                                                                                      Turbulence model 5
                                                                                                                      Experimental results
                                             Turbulence model 1
                                             Turbulence model 2
                                             Turbulence model 3
                                             Turbulence model 4
                                             Turbulence model 5
                                             Experimental results
• CFD has been around since the late 1970s, and after all these years is not that easy to compute the flow around 2D airfoils.
• In particular, predicting the maximum lift and stall characteristics is not trivial.
References:
F. Menter. “A New Generalized k-omega model. Putting flexibility into Turbulence models (GEKO)”, Ansys Germany
A. J. Wadcock. “Investigation of Low-Speed Turbulent Separated Flow Around Airfoils”, NASA Contractor Report 177450                          826
    A crash introduction to turbulence modeling in OpenFOAM®
                              Turbulence modeling in engineering
•    Most natural and engineering flows are turbulent, hence the necessity of modeling turbulence.
•    The goal of turbulence modeling is to develop equations that predict the time averaged velocity, pressure,
     temperature fields without calculating the complete turbulent flow pattern as a function of time.
•    There is no universal turbulence model, hence you need to know the capabilities and limitations of the
     turbulence models.
•    Simulating turbulent flows in any general CFD solver requires selecting a turbulence model, providing initial
     conditions and boundary conditions for the closure equations of the turbulent model, selecting a near-wall
     modeling, and choosing runtime parameters and numerics.
                                                                                                                     827
    A crash introduction to turbulence modeling in OpenFOAM®
           Convective effects
                                                             where
                                                                Viscous effects
Buoyancy effects
Momentum diffusivity
•    Notice that other factors such as free-stream turbulence, surface conditions, blowing, suction,
     roughness and other disturbances, may cause transition to turbulence at lower Reynolds
     number.
•    If you are dealing with natural convection and buoyancy, turbulent flows occurs when
                                                                                                       829
A crash introduction to turbulence modeling in OpenFOAM®
     Drag coefficient as a function of Reynolds number for    Strouhal number          for a smooth cylinder [2]
                      a smooth cylinder [1]
References:
1. Fox, Robert W., et al. Introduction to Fluid Mechanics. Hoboken, NJ, Wiley, 2010
2. Sumer, B. Mutlu, et al. Hydrodynamics Around Cylindrical Structures. Singapore, World Scientic, 2006
                                                                                                                   831
    A crash introduction to turbulence modeling in OpenFOAM®
•    The Reynold number in this case is 100, for these conditions the flow still is laminar.
•    We are in the presence of the Von Karman vortex street, which is the periodic shedding of vortices caused by
     the unsteady separation of the fluid around blunt bodies.
•    Vorticity is not a direct indication of turbulence.
•    However turbulent flows are rotational, they exhibit vortical structures.                                  832
    A crash introduction to turbulence modeling in OpenFOAM®
                                                                                              In RANS
                                                                             •   The overbar denotes the mean value.
                                                                             •   The prime denotes the fluctuating value.
                                                                                               In LES
                                                                             •   The overbar denotes the filtered value.
                                                                             •   The prime denotes the modeled value or
                                                                                 residual.
•    We have defined turbulence as an unsteady, aperiodic motion in which velocity components and every
     transported quantity fluctuate in space and time.
•    For most engineering application it is impractical to account for all these instantaneous fluctuations.
•    Therefore, we need to somehow remove those small scales by using models.
•    To remove of filter the instantaneous fluctuations or small scales, two methods can be used: Reynolds
     averaging and Filtering
•    Both methods introduce additional terms that must be modeled for closure.
•    We are going to talk about closure methods later.                                                                      833
    A crash introduction to turbulence modeling in OpenFOAM®
Laminar flow profile Averaged turbulent flow profile Instantaneous turbulent flow profile
•    In the laminar flow case, the velocity gradients close to the walls are low and the velocity profile is parabolic.
•    Turbulence has a direct effect on the velocity profiles and mixing of transported quantities.
•    The turbulent case shows two regions. One thin region close to the walls with very large velocity gradients,
     and a region far from the wall where the velocity profile is nearly uniform.
•    The thin region close to the walls is laminar.
•    Far from the flows, the flow becomes turbulent.
                                                                                                                          834
    A crash introduction to turbulence modeling in OpenFOAM®
•    Turbulence has a direct effect on the velocity profiles and mixing of transported quantities.
•    Case (a) correspond to a laminar flow, where the dye can mix with the main flow only via molecular diffusion,
     this kind of mixing can take very long times.
•    Case (b) shows a transitional state where the dye streak becomes wavy, but the main flow still is laminar.
•    Case (c) shows the turbulent state, where the dye streak changes direction erratically, and the dye has mixed
     significantly with the main flow due to the velocity fluctuations.                                          835
    A crash introduction to turbulence modeling in OpenFOAM®
                                                                                                        uffer layer
                                                                                                        iscous sublayer
Critical lengt
integral scales
inertial scales
dissipation scales
•    The use of the non-dimensional velocity u+ and non-dimensional distance from the wall y+, results in a
     predictable boundary layer profile for a wide range of flows.
•    Turbulence models require different considerations depending on whether you solve the viscous sublayer of
     model the log-law layer.                                                                                  837
A crash introduction to turbulence modeling in OpenFOAM®
                                                                                               Buffer layer
                                                                                                Viscous sublayer
                                                                                               Logarithmic layer (log-law)
Note 1: the range of y+ values might change from reference to reference but roughly speaking
they are all close to these values.
Note 2: the y+ upper limit of the buffer layer depends on the Reynolds number. Large Re will
have higher y+ upper limit                                                                                                   839
    A crash introduction to turbulence modeling in OpenFOAM®
                                             y+ insensitive
•    You can also use the y+ insensitive wall treatment (sometimes known as continuous wall functions or scalable wall functions).
•    This near-wall treatment is valid in the whole boundary layer.
•    In terms of y+, you can use this approach for values between 1 < y+ < 300.
•    This approach is very flexible as it is independent of the y+ value but is not available in all turbulence models.
•    You should also be aware of its limitations.                                                                                    840
 A crash introduction to turbulence modeling in OpenFOAM®
                                          Turbulence modeling – Grid scales
                                                                                           Cell size
                                                                              This cell is resolving the eddies
                        •   Turbulence modelling aims at predicting velocity and transported quantities fluctuations without
                            calculating the complete turbulent flow pattern as a function of time.
                        •   Everything below grid scales or sub-grid scales (SGS) is modelled or filtered.
                        •   Therefore, if we want to capture all scales we need very fine meshes in the whole domain.
MODELING APPROACH
                                                          URANS
                                         Unsteady Reynolds-Averaged Navier-Stokes equations
                                                                                                                                           complexity
                                    • Many more acronyms that fit between RANS/URANS
                                      and SRS.
                                    • Some of the acronyms are used only to differentiate
                                      approaches used in commercial solvers.
                                       PANS, SAS, RSM, EARSM, PITM, SBES, ELES
      Scale-Resolving Simulations
                                                             DES
SRS
                                                              LES
                                                       Large Eddy Simulations
                                                             DNS
                                                    Direct Numerical Simulations
                                                                                                                                                                      842
    A crash introduction to turbulence modeling in OpenFOAM®
                       Robust. Widely used despite the known limitations of the model. Performs poorly for complex
Standard k–epsilon     flows involving severe pressure gradient, separation, strong streamline curvature. Suitable for
                       initial iterations, initial screening of alternative designs, and parametric studies.
                       Suitable for complex shear flows involving rapid strain, moderate swirl, vortices, and locally
                       transitional flows (e.g. boundary layer separation, massive separation, and vortex shedding
Realizable k–epsilon   behind bluff bodies, stall in wide-angle diffusers, room ventilation). It overcome the limitations of
                       the standard k-epsilon model.
                       Superior performance for wall-bounded boundary layer, free shear, and low Reynolds number
Standard k–omega       flows compared to models from the k-epsilon family. Suitable for complex boundary layer flows
                       under adverse pressure gradient and separation (external aerodynamics and turbomachinery).
                       Offers similar benefits as standard k–omega. Not overly sensitive to inlet boundary conditions
SST k–omega            like the standard k–omega. Provides more accurate prediction of flow separation than other
                       RANS models. Probably the most widely used RANS model.
                                                                                                                          844
    A crash introduction to turbulence modeling in OpenFOAM®
                           Turbulence modeling – Starting equations
NSE
If we retain this term, we talk about URANS equations and if we drop it we talk about RANS equations
•       The differences are that all quantities have been averaged (the overbar over the primitive variables).
•       And the appearance of the Reynolds stress tensor                                               .
•       Notice that the Reynolds stress tensor is not actually a stress, it must be multiplied by density in order to have
        dimensions corresponding to stresses,
•       To derive the RANS equations we used Reynolds decomposition and a few averaging rules (a lot of algebra is
        involved),
                                                                                                                          Reynolds decomposition
                                                                                                                                                   846
    A crash introduction to turbulence modeling in OpenFOAM®
•    The Reynolds stress tensor can be modeled using the Boussinesq hypothesis, Reynolds stress models, non-
     linear eddy viscosity models or algebraic models.
•    Let us address the Boussinesq hypothesis which is the most widely used approach to model the Reynolds
     stress tensor.
•    By using this hypothesis we can relate the Reynolds stress tensor to the mean velocity gradient such that,
Effective viscosity
Turbulent viscosity
•    Notice that by introducing the Boussinesq approximation the fluctuating quantities (the prime in the equations)
     do not appear in the final equations.
•    The new equations are expressed entirely n terms of mean values (overbar), which can be computed.
•    The problem now reduces to computing the turbulent eddy viscosity              in the momentum equation.
•    This is done by adding closure models (one-equation, two-equations, algebraic, transition, Reynolds stress,
     and so on).
                                                                                                                   848
    A crash introduction to turbulence modeling in OpenFOAM®
                                       Additional remarks
•    We just outlined the incompressible RANS.
•    The compressible RANS equations are similar, but when we derive them, we use Favre average
     (which can be seen as a mass-weighted averaging), instead of Reynolds average.
•    Besides RANS, there is also LES and DES turbulence models.
•    The idea behind LES/DES models is very similar to RANS, but instead of using averaging we
     filter the equations in space, and we solve the temporal scales
•    At the end of the day, in LES/DES it is also required to model a stress tensor, usually called the
     SGS stress tensor.
•    This stress tensor is related to the scales that cannot be resolved with the mesh; therefore, need
     to be modelled.
•    LES/DES models are intrinsically unsteady and three-dimensional.
•    Let us take a look at the governing equations of the            RANS model (Wilcox 1998
     revision).
•    Remember, the main goal of the RANS turbulence models is to model the Reynolds stress
     tensor by computing the turbulent eddy viscosity.
                                                                                                      849
    A crash introduction to turbulence modeling in OpenFOAM®
•    These are the closure equations of the turbulence problem using the              RANS model.
•    These are not physical quantities. They kind of represent the generation and destruction of turbulence.
•    In the          model, the turbulent eddy viscosity can be computed as follows,
•    The model has many closure coefficient that we do not show here. These coefficients are calibrated using
     experimental data, DNS simulations, analytical solutions, or empirical data.
•    Note that all quantities are computed in function of mean values. The Reynolds stresses are modeled using
     the Boussinesq hypothesis. By proceeding in this way, we remove any dependence on the fluctuations.
•    It is worth mentioning that different turbulence models will have different ways of computing the turbulent eddy
     viscosity.                                                                                                     850
    A crash introduction to turbulence modeling in OpenFOAM®
• The initial value for the specific kinetic energy can be computed as follows,
•    If you are totally lost, you can use these reference values. They work most of the times, but it is
     a good idea to have some experimental data or a better initial estimate.
1 10 100
•    By the way, use these guidelines for external aerodynamics only.                                 851
    A crash introduction to turbulence modeling in OpenFOAM®
                                                                                                    852
    A crash introduction to turbulence modeling in OpenFOAM®
                  nut(–)WallFunction* or                            nutUSpaldingWallFunction** or
    nut           nutUSpaldingWallFunction**                        nutLowReWallFunction or fixedValue
                  (with 0 or a small number)                        (with 0 or a small number)
* $WM_PROJECT_DIR/src/TurbulenceModels/turbulenceModels/derivedFvPatchFields/wallFunctions/nutWallFunctions
** For y+ insensitive wall functions (continuous wall functions)                                                    853
    A crash introduction to turbulence modeling in OpenFOAM®
                                                                                                       855
    A crash introduction to turbulence modeling in OpenFOAM®
•    To get an initial estimate of the distance from the wall to the first cell center y+, without recurring
     to a precursor simulation, you can proceed as follows,
      1.
                                                           (Skin friction coefficient of a flat plate, there are
      2.                                                   similar correlations for pipes)
3.
      4.
                                           Your desired value
      5.
•    You will find a simple calculator for the wall distance estimation in the following link:
     http://www.wolfdynamics.com/tools.html?id=2
                                                                                                                   856
A crash introduction to turbulence modeling in OpenFOAM®
                                       where
                                        Viscous length                         857
    A crash introduction to turbulence modeling in OpenFOAM®
•    Similar to y+, the wall distance units can be computed in the stream-wise (    ) and
     span-wise (        ) directions.
•    DES and RANS simulations do not have stream-wise and span-wise wall distance units
     requirements as in LES simulations. Therefore, they are more affordable.
•    Typical requirements for LES are (these are approximations based on different references):
                                                                                                         859
    A crash introduction to turbulence modeling in OpenFOAM®
•    Always monitor the turbulent variables, some of them are positive bounded.
•    Avoid strong oscillations of the turbulent variables.
•    If you are doing LES, remember that these models are intrinsically 3D and unsteady. You should
     choose your time-step in such a way to get a CFL of less than 1 and preferably of about 0.5.
•    If you are doing RANS with wall functions, it is perfectly fine to use upwind to discretize the
     turbulence closure equations. After all, turbulence is a dissipative process. However, some
     authors may disagree with this, make your own conclusions.
•    On the other hand, if you are using a wall resolved approach, it is better to use a high-order
     discretization scheme to discretize the turbulence closure equations.
•    If you are doing unsteady simulations, always remember to compute the average values
     (ensemble average).
•    If you are dealing with external aerodynamics and detached flows, DES simulations are really
     affordable.
•    The work-horse of turbulence modeling in CFD, RANS
                                                                                                       860
       Turbulence modeling hands-on tutorials
$PTOFC/advanced_physics/turbulence/flatPlate
•   In the case directory, you will find the README.FIRST file. In this file, you will find the general instructions of
    how to run the case. In this file, you might also find some additional comments.
•   You will also find a few additional files (or scripts) with the extension .sh, namely, run_all.sh,
    run_mesh.sh, run_sampling.sh, run_solver.sh, and so on. These files can be used to run the case
    automatically by typing in the terminal, for example, sh run_solver.
•   We highly recommend to open the README.FIRST file and type the commands in the terminal, in this way
    you will get used with the command line interface and OpenFOAM® commands.
•   If you are already comfortable with OpenFOAM®, use the automatic scripts to run the cases.
                                                                                                                      861
       Turbulence modeling hands-on tutorials
                                Laminar-Turbulent flat plate
•   The best way to understand the near the wall treatment and the effect of turbulence near the
    walls, is by reproducing the law of the wall.
•   By plotting the velocity in terms of the non-dimensional variables u+ and y+, we can compare
    the profiles obtained from the simulations with the theoretical profiles.                      862
       Turbulence modeling hands-on tutorials
                                 Laminar-Turbulent flat plate
•   In the directory python of each case, you will find a jupyter notebook (a python script), that you
    can use to plot the non-dimensional u+ and y+ profiles.
•   The notebook uses some precomputed results, but you can adjust it to any case.
•   Remember, the u+ vs. y+ plot is kind of a universal plot.
•   It does not matter your geometry or flow conditions, if you are resolving well the turbulent flow,
    you should be able to recover this profile.
•   To compute this plot, you must sample the wall shear stresses and the velocity along a line
    normal to the wall.
•   Then, you can compute the shear velocity, friction coefficient, and u+ and y+ values.
                                                                                                         863
       Turbulence modeling hands-on tutorials
                                Laminar-Turbulent flat plate
•   We are going to use the following solver: simpleFoam (for RANS).
•   This case is rather simple, but we will use it to explain many features used in OpenFOAM®
    when dealing with turbulence, especially when dealing with near the wall treatment.
•   We will also show you how to do the post-processing in order to reproduce the law of the wall.
    For this, we will use a jupyter notebook (a python script).
•   Remember, as we are introducing new closure equations for the turbulence problem, we need to
    define initial and boundary conditions for the new variables.
•   We also need to define the discretization schemes and linear solvers to use to solve the new
    variables.
•   It is also a good idea to setup a few functionObjects, such as: y+, minimum and maximum
    values, forces, time average, and online sampling.
•   You will find the instructions of how to run this case in the file README.FIRST located in the
    case directory.
                                                                                                     864
       Turbulence modeling hands-on tutorials
                                     Laminar-Turbulent flat plate
•   We select the turbulence model in the momentumTransport dictionary file.
•   This dictionary file is located in the directory constant.
•   To select the K-Omega SST turbulence model,
•   Remember, you need to assign boundary and initial conditions to the new variables (k, omega,
    and nut).
                                                                                                                 865
        Turbulence modeling hands-on tutorials
                          Vortex shedding past square cylinder
•   To define the wall functions, follow this table,
                                     omegaWallFunction               omegaWallFunction
    omega
$PTOFC/advanced_physics/turbulence/squarecil
•   In the case directory, you will find the README.FIRST file. In this file, you will find the general instructions of
    how to run the case. In this file, you might also find some additional comments.
•   You will also find a few additional files (or scripts) with the extension .sh, namely, run_all.sh,
    run_mesh.sh, run_sampling.sh, run_solver.sh, and so on. These files can be used to run the case
    automatically by typing in the terminal, for example, sh run_solver.
•   We highly recommend you to open the README.FIRST file and type the commands in the terminal, in this
    way, you will get used with the command line interface and OpenFOAM® commands.
•   If you are already comfortable with OpenFOAM®, use the automatic scripts to run the cases.
                                                                                                                      867
Turbulence modeling hands-on tutorials
       Vortex shedding past square cylinder
                                                                               868
           Turbulence modeling hands-on tutorials
                                       Vortex shedding past square cylinder
References:
Lyn, D.A. and Rodi, W., The flapping shear layer formed by flow separation from the forward corner of a square cylinder. J. Fluid Mech., 267, 353, 1994.
Lyn, D.A., Einav, S., Rodi, W. and Park, J.H., A laser-Doppler velocimetry study of ensemble-averaged characteristics of the turbulent near wake of a square
cylinder. Report. SFB 210 /E/100.
                                                                                                                                                               869
        Turbulence modeling hands-on tutorials
                           Vortex shedding past square cylinder
•   We will use this case to learn how to setup a turbulent case (RANS and LES).
•   To run this case we will use the solvers simpleFoam (steady solver) and pimpleFoam
    (unsteady solver).
•   To get fast outcomes, we will use a coarse mesh. But feel free to refine the mesh, especially
    close to the walls.
•   Remember, as we are introducing new closure equations for the turbulence problem, we need to
    define initial and boundary conditions for the new variables.
•   We will use a few functionObjects to compute some additional quantities, such as, Q criterion,
    y+, minimum and maximum values, forces, time average, and online sampling.
•   After finding the solution, we will visualize the results.
•   We will also compare the numerical solution with the experimental results.
•   At the end, we will do some plotting and advanced post-processing using gnuplot and Python.
•   Have in mind that the unsteady case will generate a lot of data.
•   You will find the instructions of how to run this case in the file README.FIRST located in the
    case directory.
                                                                                                     870
       Turbulence modeling hands-on tutorials
                           Vortex shedding past square cylinder
•   We select the turbulence model in the momentumTransport dictionary file.
•   This dictionary file is located in the directory constant.
•   To select the LES (Smagorinsky) turbulence model,
           27           delta           cubeRootVol;
           31           cubeRootVolCoeffs
                                                                                         LES filter
           32           {
           33                deltaCoeff      1;
           34           }
           100    }
•   Remember, you need to assign boundary and initial conditions to the new variables (nut).
                                                                                                                871
         Turbulence modeling hands-on tutorials
                          Vortex shedding past square cylinder
•   To define the wall functions, follow this table,
                                     omegaWallFunction          omegaWallFunction
    omega
•   Run using the following combinations of wall functions and compare the outcome.
     •      Use High RE for RANS.
     •      Use High RE and Low RE for URANS.
     •      Use High RE and Low RE for LES.
                                                                                                 872
       Turbulence modeling hands-on tutorials
                           Vortex shedding past square cylinder
•   The initial value for the turbulent kinetic energy         can be found as follows,
• The initial value for the specific kinetic energy can be found as follows,
•   At this point, we are ready to run. But before running, remember to setup the right numerics in
    the dictionary files fvSolution and fvSchemes.
•   For the LES simulation, try to keep the CFL number below 0.9. For the URANS simulation, you
    can go as high as 10.
•   Finally, do not forget to setup the functionObjects to compute the forces, average values, do
    the sampling, and compute y+ on-the-fly.
                                                                                                    873
                 Roadmap
                                          874
    A crash introduction to multiphase flows modeling OpenFOAM®
                                                                                                 875
A crash introduction to multiphase flows modeling OpenFOAM®
                                                                                            Propeller cavitation
                                                                                            http://www.veempropellers.com/features/cavitationresistance
  Siltation & Sedimentation
  http://blackwarriorriver.org/siltation-sedimentation/
                                                                                                                                                                                                     876
A crash introduction to multiphase flows modeling OpenFOAM®
   Fermentation of beer and spirits                                                        Chemical reactor for the pharmaceutical and
   http://www.distillingliquor.com/2015/02/05/how-to-make-alcohol-and-spirits/             biotechnology industry
                                                                                           http://www.total-mechanical.com/Industrial/CaseStudies.aspx
                                                                                                                                                                        877
    A crash introduction to multiphase flows modeling OpenFOAM®
                                                                                                   878
    A crash introduction to multiphase flows modeling OpenFOAM®
•   Disperse system: the phase is dispersed as non-contiguous isolated regions within the other
    phase (the continuous phase) . When we work with a disperse phase, we say that the system is
    dispersed: disperse-continuous flow.
•   Separated system: the phase is contiguous throughout the domain and there is one well
    defined interphase with the other phase. When we work with continuous phases, we say that the
    system is separated: continuous-continuous flow.
                                                                                               879
    A crash introduction to multiphase flows modeling OpenFOAM®
Increase
                                                                                                          Modeling requirements
•   Fully resolved: solves complete physics. All spatial and temporal scales
    are resolved. Equivalent to DNS in turbulence modelling.
                                                                                  Computational power
    transported with the flow. One- or two-way coupling is possible. It can
    account for turbulence, momentum transfer, and mass transfer.
                                                                                                                                  880
    A crash introduction to multiphase flows modeling OpenFOAM®
                                               VOF ≈ 0.5
                                               Average phase
                                               properties
            In theory, the VOF method can resolve the smallest bubbles/droplets but the mesh requirements are
               too prohibitive (equivalent to DNS). In multiphase flows, this is called fully resolved approach.
                                                                                                                   881
  A crash introduction to multiphase flows modeling OpenFOAM®
                                                                         882
    A crash introduction to multiphase flows modeling OpenFOAM®
       Eulerian-Eulerian                      Eulerian-Eulerian
                                                                                    Eulerian-Lagrangian
             (VOF)                          (Dispersed systems)
                                                                                                                    885
    A crash introduction to multiphase flows modeling OpenFOAM®
www.wolfdynamics.com/training/mphase/image10.gif http://www.wolfdynamics.com/training/mphase/image16.gif
http://www.wolfdynamics.com/training/mphase/image2.gif http://www.wolfdynamics.com/training/mphase/image3.gif
•   Simulation showing free surface tracking, bubble tracking, bubble coalescence, bubble break-up and wake
    entrainment using the VOF method.
•   In this simulation the free surface and bubbles are capture by using AMR.
•   However, the smallest bubble that can be resolved is at the smallest grid size.                                  887
    A crash introduction to multiphase flows modeling OpenFOAM®
http://www.wolfdynamics.com/training/mphase/image18.gif
References:
[1] Vivek V. Buwa, Vivek V. Ranade, Dynamics of gas–liquid flow in a rectangular bubble column: experiments and single/multi-group CFD simulations.
Chemical Engineering Science 57 (2002) 4715 – 4736                                                                                                    888
    A crash introduction to multiphase flows modeling OpenFOAM®
                  twoPhaseEulerFoam                                              twoPhaseEulerFoam
                   Air volume fraction                                            Air volume fraction
                     Turbulent case                                                  Laminar case
         http://www.wolfdynamics.com/training/mphase/image42.gif        http://www.wolfdynamics.com/training/mphase/image41.gif
                             DPMFoam                                            twoPhaseEulerFoam
        Particle-particle interactions colored by velocity                       Air volume fraction
                magnitude (particles not to scale)                                 Turbulent case
    http://www.wolfdynamics.com/training/mphase/image43.gif    http://www.wolfdynamics.com/training/mphase/image42.gif
                                                                                               Source terms:
                                                                                               •   Porous media
                                                                                               •   Coriolis forces
                                                                                               •   Centrifugal forces
                                Surface tension - Continuum surface force (CSF)                •   Mass transfer
                                                                                               •   and so on …
•   You can see the volume fraction      as a pointer that indicates what phase (with the
    corresponding physical properties), is inside each cell of the computational domain.                                891
    A crash introduction to multiphase flows modeling OpenFOAM®
• The fluid properties can be written on either side of the interface as follows,
                                                                                                      892
    A crash introduction to multiphase flows modeling OpenFOAM®
                                                                                                         Source terms:
                                                                                                         •   Porous media
                                                                                                         •   Coriolis forces
                                                                                                         •   Centrifugal forces
                                                                                                         •   Mass transfer
                                                                                                         •   and so on …
                                                                                                                          893
    A crash introduction to multiphase flows modeling OpenFOAM®
                                                                                        896
             Multiphase flows hands-on tutorials
$PTOFC/advanced_physics/multiphase/wigleyHull
•   In the case directory, you will find the README.FIRST file. In this file, you will find the general instructions of
    how to run the case. In this file, you might also find some additional comments.
•   You will also find a few additional files (or scripts) with the extension .sh, namely, run_all.sh,
    run_mesh.sh, run_sampling.sh, run_solver.sh, and so on. These files can be used to run the case
    automatically by typing in the terminal, for example, sh run_solver.
•   We highly recommend to open the README.FIRST file and type the commands in the terminal, in this way
    you will get used with the command line interface and OpenFOAM® commands.
•   If you are already comfortable with OpenFOAM®, use the automatic scripts to run the cases.
                                                                                                                      897
Multiphase flows hands-on tutorials
    Free surface – Ship resistance simulation
Drag coefficient
                                                                                                                     899
                       Multiphase flows hands-on tutorials
                                             Free surface – Ship resistance simulation
•        We are going to use the following solver: interFoam
•        The first step is to set the physical properties. In the dictionary
         constant/transportProperties we defined the phases.
•        Go to the directory constant and open the dictionary transportProperties.
                                                                        The first phase is always considered the primary phase
                                                                                                                                 900
            Multiphase flows hands-on tutorials
                       Free surface – Ship resistance simulation
•   The next step is to set the boundary conditions and initial conditions.
•   Therefore, in the directory 0 we define the dictionary alpha.water that will take the values of
    the phase water.
•   In this case, you will find the directory 0_org, here is where we keep a backup of the original
    files as we are doing field initialization using setFields.
•   In the directory 0, you will find the dictionary p_rgh, in this dictionary we set the boundary and
    initial conditions for the pressure field, and the dimensions are in Pascals.
•   The turbulence variables values were calculated using an eddy viscosity ratio equal to 1,
    turbulence intensity equal 5%, and the water properties.
•   If you are simulating numerical towing tanks, the setup of the boundary conditions is always the
    same.
•   Feel free to reuse this setup.
•   The dictionaries used in this case are standard for the VOF solvers (interFoam family solvers).
•   If you are using a different solver (e.g., twoPhaseEulerFoam), you will need to use additional
    dictionaries where you define the interfacial models and so on.
•   Remember, you should always conduct production runs using a second order discretization
    scheme
                                                                                                      901
         Multiphase flows hands-on tutorials
                       Free surface – Ship resistance simulation
                                                              Opening
     Air phase                            Wall
Inlet outlet
Note:
Phases must be initialized
on the internal cells and
boundary faces
                                                                        Symmetry
                              Physical domain and boundary patches                          902
           Multiphase flows hands-on tutorials
                        Free surface – Ship resistance simulation
                                                                         fixedValue
inflow       fixedFluxPressure             fixedValue                                                fixedValue
                                                                         calculated (nut)
                                                                         inletOutlet
outflow      inletOutlet or zeroGradient   outletPhaseMeanVelocity                                   variableHeightFlowRate
                                                                         calculated (nut)
                                                                         inletOutlet
top          totalPressure                 pressureInletOutletVelocity                               inletOutlet
                                                                         calculated (nut)
                                                                         kqRWallFunction (k)
ship         fixedFluxPressure             fixedValue                    omegaFunction (omega)       zeroGradient
                                                                         nutkWallFunction (nut)
                        Typical setup of boundary conditions for numerical towing tank simulations                            903
            Multiphase flows hands-on tutorials
                        Free surface – Ship resistance simulation
•   OpenFOAM® solves the following modified volume fraction convective equation to track the
    interface between the phases,
                                                                                                      904
           Multiphase flows hands-on tutorials
                      Free surface – Ship resistance simulation
•   MULES options in the fvSolution dictionary.
•   The semi-implicit MULES offers significant speed-up and stability over the explicit MULES.
       “alpha.*”
       {
            MULESCorr                yes;              Turn on/off semi-implicit MULES
            nAlphaSubCycles          1;                For semi-implicit MULES use 1. Use 2 or more for
                                                       explicit MULES.
            nAlphaCorr               3;                Number of corrections.
                                                       Use 2-3 for slowly varying flows.
                                                       Use 3 or more for highly transient, high Reynolds,
                                                       high CFL number flows.
•   If you are planning to use large time-steps (CFL number larger than 1), it is recommended to do
    at least 3 nCorrector, otherwise you can use 2.
                                                                                                      906
                                        Multiphase flows hands-on tutorials
                                                Free surface – Ship resistance simulation
  •                           Finally, we need to set the discretization schemes
  •                           This is done in the dictionary fvSchemes.
  •                           In this dictionary we set the discretization method for every term appearing in the governing
                              equations.
  •                           Convective terms discretization is set as follows:
                                    divSchemes
                                    {
This term is related to the
volume fraction equation
• Notice that we are using a high-resolution scheme for the surface tracking (div(phi,alpha)).
                                                                                                                              907
           Multiphase flows hands-on tutorials
                       Free surface – Ship resistance simulation
•   For time discretization we can use an unsteady formulation (Euler in this case).
•   This scheme requires setting the time-step, and it should be choosing in such a way that it
    resolves the mean physics.
•   Remember, as the free surface is a strong discontinuity, for stability and good resolution we
    need to use a CFL less than one for the interface courant.
                               ddtSchemes
                               {
                                   default Euler;
                               }
•   Hereafter, we are using what is know as global time stepping, that is, the CFL number is limited
    by the smallest cell.
•   The simulation is time-accurate, but it requires a lot of CPU time to reach a steady state (if it
    reaches one).
                                                                                                        908
           Multiphase flows hands-on tutorials
                      Free surface – Ship resistance simulation
•   A way to accelerate the convergence to steady state, is by using local time stepping (LTS).
•   In LTS, the time-step is manipulated for each individual cell in the mesh, making it as high as
    possible to enable the simulation to reach steady-state quickly.
•   When we use LTS, the transient solution is no longer time accurate.
•   The stability and accuracy of the method are driven by the local CFL number of each cell.
•   To avoid instabilities caused by sudden changes in the time-step of each cell, the local time-
    step can be smoothed and damped across the domain.
•   Try to avoid having local time-steps that differ by several order of magnitudes.
•   To enable LTS, we use the localEuler method.
                              ddtSchemes
                              {
                                  default localEuler;
                              }
•   LTS in OpenFOAM® can be used with any solver that supports the PISO or PIMPLE loop
    (PISO ITA).                                                                                       909
            Multiphase flows hands-on tutorials
                     Free surface – Ship resistance simulation
•   In the LTS method, the maximum flow CFL number, maximum interface CFL number, and the
    smoothing and damping of the solution across the cells, can be controlled in the dictionary
    fvSolution, in the sub-dictionary PIMPLE.
                         PIMPLE
                         {
                             momentumPredictor              yes;
                              nOuterCorrectors              2;
                              nCorrector                    3;
                              nNonOrthogonalCorrectors      2;
                                                                                                  910
            Multiphase flows hands-on tutorials
                       Free surface – Ship resistance simulation
•   At this point, we are ready to run the simulation.
•   Remember to adjust the numerics according to your physics.
•   You can choose between running using global time stepping or unsteady (directory uns) or local
    time stepping (directory LTS).
•   You will find the instructions of how to run the cases in the file README.FIRST located in the
    case directory.
                                                                                                     911
                 Roadmap
                                          912
A crash introduction to compressible flows modeling OpenFOAM®
                                                                                                  913
A crash introduction to compressible flows modeling OpenFOAM®
    Large Natural Convection Plume, as effect of combustion of excess                  Rayleigh–Bénard convection cells
    non-useable gases behind oilfield.                                                 https://en.wikipedia.org/wiki/File:B%C3%A9nard_cells_convection.ogv
    https://en.wikipedia.org/wiki/Plume_(fluid_dynamics)#/media/File:Naturalc
    onvectionplume.JPG
Copyright on the images is held by the contributors. Apart from Fair Use, permission must be sought for any other purpose                               915
A crash introduction to compressible flows modeling OpenFOAM®
Copyright on the images is held by the contributors. Apart from Fair Use, permission must be sought for any other purpose   916
A crash introduction to compressible flows modeling OpenFOAM®
NSE
 Additional closure equations for turbulence models, multiphase models, combustion, particles,
                                     source terms, and so on
                                                                                                 917
A crash introduction to compressible flows modeling OpenFOAM®
            Thermal boundary layer vs. Viscous boundary layer        Thermal boundary layer in function of Prandtl number (Pr)
                          Forced convection
•   Just as there is a viscous (or momentum) boundary layer in the velocity distribution, there is also a thermal
    boundary layer.
•   Thermal boundary layer thickness is different from the thickness of the viscous sublayer (or momentum), and
    is fluid dependent.
•   The thickness of the thermal sublayer for a high Prandtl number fluid (e.g. water) is much less than the
    momentum sublayer thickness.
•   For fluids of low Prandtl numbers (e.g., air), it is much larger than the momentum sublayer thickness.
•   For Prandtl number equal 1, the thermal boundary layer is equal to the momentum boundary layer.                              918
A crash introduction to compressible flows modeling OpenFOAM®
          Horizontal heated plate immersed in a quiescent fluid.                         Vertical heated plate immersed in a quiescent fluid.
                           Natural convection                                                            Natural convection.
•   As the fluid is warmed by the plate, its density decreases, and a buoyant force arises which induces flow
    motion in the vertical or horizontal direction.
•   The force is proportional to                                   , therefore gravity must be considered.                                      919
A crash introduction to compressible flows modeling OpenFOAM®
                                                                                                    920
A crash introduction to compressible flows modeling OpenFOAM®
                                                                                                       921
A crash introduction to compressible flows modeling OpenFOAM®
                                                                                             922
A crash introduction to compressible flows modeling OpenFOAM®
     •   High-speed aerodynamics:
               • rhoSimpleFoam, rhoPimpleFoam, rhoCentralFoam
                                                                                          923
A crash introduction to compressible flows modeling OpenFOAM®
                                                                                                               926
A crash introduction to compressible flows modeling OpenFOAM®
                                                                                                              927
A crash introduction to compressible flows modeling OpenFOAM®
    divSchemes                                         “( |    )”
    {                                                  {
         div(phi,K) Gauss linear;                             solver           PBiCGStab;
         div(phi,h) Gauss linear;                             preconditioner   DILU;
         div(phid,p) Gauss linear;                            tolerance        1e-8;
         …                                                    relTol           0.01;
         …                                             }
         …                                                    …
    }                                                         …
                                                              …
    divSchemes                                         “( |    )”
    {                                                  {
         div(phi,K) Gauss linear;                             solver           PBiCGStab;
         div(phi,e) Gauss linear;                             preconditioner   DILU;
         div(phiv,p) Gauss linear;                            tolerance        1e-8;
         …                                                    relTol           0.01;
         …                                             }
         …                                                    …
    }                                                         …
                                                              …
                                           Final remarks
•   When solving the enthalpy formulation of the energy equation,
•   This has a stabilizing effect on the solution, specially if you are using steady solvers.
•   To turn off the pressure work term , set the option dpdt to no ( dpdt no; ) in the
    thermophysicalProperties dictionary.
•   Finally, when you work with compressible solvers you use absolute pressure
    and the working units are in Pascals.
                                                                                                930
         Compressible flows hands-on tutorials
$PTOFC/advanced_physics/compressible/supersonic_cyl
•   In the case directory, you will find the README.FIRST file. In this file, you will find the general instructions of
    how to run the case. In this file, you might also find some additional comments.
•   You will also find a few additional files (or scripts) with the extension .sh, namely, run_all.sh,
    run_mesh.sh, run_sampling.sh, run_solver.sh, and so on. These files can be used to run the case
    automatically by typing in the terminal, for example, sh run_solver.
•   We highly recommend to open the README.FIRST file and type the commands in the terminal, in this way
    you will get used with the command line interface and OpenFOAM® commands.
•   If you are already comfortable with OpenFOAM®, use the automatic scripts to run the cases.
                                                                                                                      931
         Compressible flows hands-on tutorials
                         2D supersonic cylinder – Shock waves
•   Shock waves are strong discontinuities that need to be treated using high resolution schemes.
•   Additionally, the non-orthogonality add extra complications to this problem.
                                                                                                    932
     Compressible flows hands-on tutorials
                             2D supersonic cylinder – Shock waves
                                                                                                                              933
         Compressible flows hands-on tutorials
                         2D supersonic cylinder – Shock waves
•   In this case we will use the solver rhoPimpleFoam with transonic corrections.
•   By enabling transonic correction we can use this solver to tackle trans-sonic/supersonic flows.
•   Transonic corrections are enabled in the PIMPLE block of the dictionary fvSolution,
           •   transonic yes;
•   rhoPimpleFoam is an unsteady solver, but if you are interested in a steady solution you can
    use local time stepping.
•   As the flow is compressible, we need to define the thermodynamical properties of the working
    fluid.
•   This is done in the dictionary constant/thermophysicalProperties.
•   We also need to define the boundary conditions and initial conditions for the temperature field.
•   Additionally, if you are using a turbulence model, you will need to define wall functions for the
    thermal diffusivity.
           •   The rest of the turbulent variables are defined as in incompressible flows.
•   Finally, adjust the numerics according to your physics.
•   You will find the instructions of how to run the cases in the file README.FIRST located in the
    case directory.
                                                                                                        934
                 Roadmap
                                          935
         A crash introduction to moving bodies OpenFOAM®
   Prescribed motion with multiple bodies                                 Layering with mesh zones interface
http://www.wolfdynamics.com/training/dynamicMeshes/meshMotion1      http://www.wolfdynamics.com/training/dynamicMeshes/layeringMesh.gif936
               A crash introduction to moving bodies OpenFOAM®
•   Setting moving bodies simulations is not so different from what we have done so far.
•   The main difference is that we must assign a motion type to a surface patch, a cell region, or the
    whole domain.
                                                                                                   938
            A crash introduction to moving bodies OpenFOAM®
                                                                                                     939
               A crash introduction to moving bodies OpenFOAM®
$PTOFC/advanced_physics/sliding_meshes_MRF/CSTR
•   In the case directory, you will find the README.FIRST file. In this file, you will find the general instructions of
    how to run the case. In this file, you might also find some additional comments.
•   You will also find a few additional files (or scripts) with the extension .sh, namely, run_all.sh,
    run_mesh.sh, run_sampling.sh, run_solver.sh, and so on. These files can be used to run the case
    automatically by typing in the terminal, for example, sh run_solver.
•   We highly recommend to open the README.FIRST file and type the commands in the terminal, in this way
    you will get used with the command line interface and OpenFOAM® commands.
•   If you are already comfortable with OpenFOAM®, use the automatic scripts to run the cases.
                                                                                                                      941
               Moving bodies hands-on tutorials
         Continuous stirring tank reactor – Sliding meshes and MRF
                                                                                                                                942
              Moving bodies hands-on tutorials
          Continuous stirring tank reactor – Sliding meshes and MRF
•   We already created this mesh during the meshing module.
•   We will only address the differences in meshing for an MRF simulation and a sliding mesh
    simulation.
•   In this case, at the end of the meshing stage we obtained a faceZone and a cellZone.
•   This is a conforming mesh, that is, the cells in the interface of the inner and outer regions are
    perfectly matching.
•   For MRF simulations, the cellZone can be used to assign the MRF properties to the rotating
    zone.
•   For sliding meshes or non-conforming meshes, there is an extra step where we need to split the
    mesh in two regions and create the interface patches between the fix zone and the rotating
    zone (the solution will be interpolated in these patches).
                                                                        Cell region 2
                                                                        (fix region)s
                                                                                                  943
                Moving bodies hands-on tutorials
           Continuous stirring tank reactor – Sliding meshes and MRF
•   In the MRF approach, the governing equations are solved in a relative rotating frame in the
    selected rotating zone.
•   Additional source terms that model the rotation effect are taken into account.
•   You select the rotating zone and set the rotation properties in the dictionary
    constant/MRFProperties.
•   In this case, the mesh is conforming.
                                                                    Shaft
                                                                    type rotatingWallVelocity;
                                                                    origin (0 0 0);
                                                                    axis (0 0 1);
                                                                    omega constant 12.566370;
                                                                    value uniform (0 0 0);
    Impeller
    type movingWallVelocity;
    value uniform (0 0 0);                                          Inner region generated during
                                                                    meshing - MRFProperties
                                                                                                    944
                Moving bodies hands-on tutorials
           Continuous stirring tank reactor – Sliding meshes and MRF
•   In the sliding meshes approach, the selected rotating region is physically rotating.
•   As the meshes are non-conforming, the solution between the rotating region and the fix region
    must be interpolated using arbitrary mesh interface.
•   In the sliding meshes approach, is not enough to only identify the rotating region.
•   We also need to create the interface patches between the fix zone and the rotating zone.
                                                                 Shaft
                                                                 type rotatingWallVelocity;
                                                                 origin (0 0 0);
                                                                 axis (0 0 1);
                                                                 omega constant 12.566370;
                                                                 value uniform (0 0 0);
    Impeller
    type movingWallVelocity;
    value uniform (0 0 0);                                       Inner region – dynamicMeshDict
                                                                                                  945
               Moving bodies hands-on tutorials
          Continuous stirring tank reactor – Sliding meshes and MRF
                                                                         Shaft
                                                                         type rotatingWallVelocity;
                                                                         origin (0 0 0);
                                                                         axis (0 0 1);
                                                                         omega constant 12.566370;
                                                                         value uniform (0 0 0);
   Impeller
   type movingWallVelocity;
   value uniform (0 0 0);                                                Inner region and arbitrary mesh
                                                                         interface
                                                         cellZone cell_inner_volume;
   dynamicFvMesh        dynamicMotionSolverFvMesh;       active  yes;
   motionSolverLibs ( "libfvMotionSolvers.so" );
   solver               solidBody;                       // Fixed patches (by default they move’ with the MRF zone)
   cellZone             cell_inner_volume;               nonRotatingPatches ();
   solidBodyMotionFunction rotatingMotion;
   origin (0 0 0);                                       origin (0 0 0);
   axis   (0 0 1);                                       axis   (0 0 1);
   omega constant 12.566370;                             omega constant 12.566370;
                                                                                                                      946
              Moving bodies hands-on tutorials
          Continuous stirring tank reactor – Sliding meshes and MRF
•   For siding meshes, we need to create separated regions.
•   In this case, to create the two regions we proceed as follows,
•   In step 1, we split the mesh in regions using the baffles (faceZone), created during the meshing
    stage.
•   We also create the cyclicAMI patches AMI1 and AMI2.
•   At this point we have two regions and one zone. However, the two regions are stich together
    via the patches AMI1 and AMI2.
•   In step 2, we topologically split the patches AMI1 and AMI2. As we removed the link between
    AMI1 and AMI2, the regions are free to move.
                                                                                                  947
                      Moving bodies hands-on tutorials
             Continuous stirring tank reactor – Sliding meshes and MRF
•   The utility createBaffles, reads the dictionary createBafflesDict.
•   With this utility we create the interface patches between the fix zone and the rotating zone.
        baffles
        {
                  rotating                                                Name of the baffle group
                  {
                             type faceZone;                               Use faceZone
                             zoneName face_inner_volume;                  Face to use to construct the AMI patches.
                                                                          The name was defined in snappyHexMeshDict
                             patches
                             {
                                       master                             Parameters for the master patch
                                       {
                                                name AMI1;                Name of the master patch (user defined)
     Boundary condition                         type cyclicAMI;
     for sliding grids                          matchTolerance 0.0001;
                                                neighbourPatch AMI2;      Neighbour patch (slave patch or AMI2)
                                                transform none;
                                       }
                                       slave                              Parameters for the slave patch
                                       {
     Boundary condition                         name AMI2;                Name of the slave patch (user defined)
                                                type cyclicAMI;
     for sliding grids                          matchTolerance 0.0001;
                                                neighbourPatch AMI1;      Neighbour patch (master patch or AMI1)
                                                transform none;
                                       }
                             }
                  }
        }                                                                Initially, the master and slave patches
                                                                         share a common face
                                                                                                                      948
                    Moving bodies hands-on tutorials
             Continuous stirring tank reactor – Sliding meshes and MRF
•    In sliding mesh simulations, the solution is interpolated back-and-forth between the regions.
•    The interpolation is done at the arbitrary mesh interface patches (AMI) .
•    To reduce interpolation errors at the AMI patches, the meshes should be similar in the master
     and slave patches.
http://www.wolfdynamics.com/training/movingbodies/image8.gif
                                                                                                                       949
              Moving bodies hands-on tutorials
          Continuous stirring tank reactor – Sliding meshes and MRF
•   At this point, the mesh is ready to use.
•   You can visualize the mesh using paraFoam.
•   If you use checkMesh, it will report that there are two regions.
•   In the dictionary constant/dynamicsMeshDict we set which region will move and the
    rotation parameters.
•   To preview the region motion, in the terminal type:
          •    $> moveDynamicMesh
•   To preview the region motion and check the quality of the AMI interfaces, in the terminal type:
          •    $> moveDynamicMesh -checkAMI -noFunctionObjects
• In our YouTube channel you can find a step-by-step video explaining this case.
                                                                                                      950
                Moving bodies hands-on tutorials
           Continuous stirring tank reactor – Sliding meshes and MRF
    Calculating AMI weights between owner patch: AMI1 and neighbour patch: AMI2
                                                                                                        Number of faces in
    AMI: Creating addressing and weights between 2476 source faces and 2476 target faces                the AMI patches
AMI: Patch source sum(weights) min/max/average = 0.94746705, 1.0067199, 0.99994232 AMI1 patch weights
AMI: Patch target sum(weights) min/max/average = 0.94746692, 1.0004497, 0.99980782 AMI2 patch weights
    …
    …
    …
                                                                                                                                 951
               Moving bodies hands-on tutorials
           Continuous stirring tank reactor – Sliding meshes and MRF
•   At this point, we are ready to run the simulation.
•   You can choose between running using sliding meshes (directory sliding_piso) or MRF
    (directory MRF_simple).
•   You can use the solver pimpleFoam for sliding meshes and the solver simpleFoam for MRF.
•   You can also use pimpleFoam (unsteady solution) for the MRF. However, it is not
    computationally efficient, the idea of MRF is to reach a steady solution fast.
•   You can also try pimpleFoam (with local time stepping (LTS).
•   You will find the instructions of how to run the cases in the file README.FIRST located in the
    case directory.
                                                                                                     952
                Moving bodies hands-on tutorials
$PTOFC/advanced_physics/prescribed_motion/oscillatingCylinder
•   In the case directory, you will find the README.FIRST file. In this file, you will find the general instructions of
    how to run the case. In this file, you might also find some additional comments.
•   You will also find a few additional files (or scripts) with the extension .sh, namely, run_all.sh,
    run_mesh.sh, run_sampling.sh, run_solver.sh, and so on. These files can be used to run the case
    automatically by typing in the terminal, for example, sh run_solver.
•   We highly recommend to open the README.FIRST file and type the commands in the terminal, in this way
    you will get used with the command line interface and OpenFOAM® commands.
•   If you are already comfortable with OpenFOAM®, use the automatic scripts to run the cases.
                                                                                                                      953
Moving bodies hands-on tutorials
    Oscillating cylinder – Prescribed motion
Moving boundary
http://www.wolfdynamics.com/training/movingbodies/image10.gif
                                                                                                    954
                                Moving bodies hands-on tutorials
                                         Oscillating cylinder – Prescribed motion
•                     In the dictionary constant/dynamicMeshDict we select the mesh morphing method and the
                      boundary patch that it is moving (lines 21 and 25, respectively).
•                     There are many mesh morphing methods implemented in OpenFOAM®.
•                     Mesh morphing is based in diffusing or propagating the mesh deformation all over the domain.
•                     You will need to find the best method for your case.
•                     The setup used in this case works fine most of the times.
                37   in
                38   {
                39         type               fixedValue;
                40         value              uniform (0 0 0);
                41   }
                42   cylinder
                43   {
                44       type                 oscillatingDisplacement;
                45       amplitude            ( 0 1 0 );
                46       omega                6.28318;
                47       value                uniform ( 0 0 0 );                 Dummy value for paraview
                48   }
                                                                                                            956
              Moving bodies hands-on tutorials
                        Oscillating cylinder – Prescribed motion
•   You must assign the boundary condition movingWallVelocity to all patches that are moving.
•   This is done in the dictionary 0/U.
                  41   cylinder
                  42   {
                  43       type                movingWallVelocity;
                  44       value               uniform (0 0 0);
                  45   }
•   And as usual, you will need to adjust the numerics according to your physics.
•   In this case we need to solve the new fields cellDisplacement and diffusivity, which are
    related to the mesh motion and morphing.
•   In the dictionary fvSolution, you will need to add a linear solver for the field
    cellDisplacement.
•   In the dictionary fvSchemes, you will need to add the discretization schemes related to the
    mesh morphing diffusion method, laplacian(diffusivity, cellDisplacement).
•   If you are dealing with turbulence modeling the treatment of the wall functions is the same as if
    you were working with fixed meshes.                                                              957
               Moving bodies hands-on tutorials
                        Oscillating cylinder – Prescribed motion
•   At this point, we are ready to run the simulation.
•   You will find the instructions of how to run the cases in the file README.FIRST located in the
    case directory.
•   Before running the simulation, you can check the mesh motion.
•   During this check, you can use large time-steps as we re not computing the solution, we are
    only interested in checking the motion.
•   To check the mesh motion, type in the terminal:
                                                                                                     958
                Moving bodies hands-on tutorials
$PTOFC/advanced_physics/rigid_body_motion/floatingObject
•   In the case directory, you will find the README.FIRST file. In this file, you will find the general instructions of
    how to run the case. In this file, you might also find some additional comments.
•   You will also find a few additional files (or scripts) with the extension .sh, namely, run_all.sh,
    run_mesh.sh, run_sampling.sh, run_solver.sh, and so on. These files can be used to run the case
    automatically by typing in the terminal, for example, sh run_solver.
•   We highly recommend to open the README.FIRST file and type the commands in the terminal, in this way
    you will get used with the command line interface and OpenFOAM® commands.
•   If you are already comfortable with OpenFOAM®, use the automatic scripts to run the cases.
                                                                                                                      959
           Moving bodies hands-on tutorials
                                                            Floating body – Rigid body motion
ime/ s
                                                                              http://www.wolfdynamics.com/training/movingbodies/image11.gif
               t v s o ientation u   (acos(   )    /pi/ )
position
c
ime/ s
http://www.wolfdynamics.com/training/movingbodies/image12.gif
    23   sixDoFRigidBodyMotionCoeffs
    24   {
    25       patches         (floatingObject);                      Moving patch
    26
                                                 Mesh deformation limits.
    27       innerDistance    0.1;
                                                 The mesh will not be deformed in the fringe located within
    28       outerDistance    0.4;
                                                 innerDistance and outerDistance (distance normal to the wall)
    33       centreOfMass    (0.5 0.5 0.5);
    34       mass            5;                                      Physical properties of the body
    35       momentOfInertia (0.08 0.08 0.1);
                                                                                                     innerDistance
                                       Set it to zero if you do not want to apply mesh morphing to the inner region    962
               Moving bodies hands-on tutorials
                            Floating body – Rigid body motion
•   The dictionary constant/dynamicMeshDict (continuation).
      50       constraints
      51       {
      55           fixedAxis
      56           {
      57               sixDoFRigidBodyMotionConstraint axis;
      58               axis (0 1 0);
      59           }                                            Motion constraints
                                                                If you do not give any
      63           fixedLine                                    constraint, the body is free
      64           {                                            to move in all directions.
      65               sixDoFRigidBodyMotionConstraint line;
      66               centreOfRotation (0.5 0.5 0.5);
      67               direction (0 0 1);
      68           }
      70       }
                                                                 Body restraints
      72       restraints
                                                                 Restraints can be used to
      73       {
                                                                 damp the acceleration of the
                                                                 body.
      75       }
                                                                 In this case, we are not
                                                                 using restraints
      77   }
                                                                                          963
              Moving bodies hands-on tutorials
                            Floating body – Rigid body motion
•   In the dictionary 0/pointDisplacement we select the body motion.
•   For rigid body motion, the body motion is computed by the solver, therefore, we use the
    boundary condition calculated.
                  33   floatingObject
                  34   {
                  35       type                calculated;
                  36       value               uniform (0 0 0);
                  37   }
•   You must assign the boundary condition movingWallVelocity to all patches that are moving.
    This is done in the dictionary 0/U.
                  33   floatingObject
                  34   {
                  35       type                movingWallVelocity;
                  36       value               uniform (0 0 0);
                  37   }
•   If you are dealing with turbulence modeling the treatment of the wall functions is the same as if
    you were working with fixed meshes.                                                              964
               Moving bodies hands-on tutorials
                            Floating body – Rigid body motion
•   And as usual, you will need to adjust the numerics according to your physics.
•   In the case directory, you will find the script extractData.
•   This script can be used to extract the position of the body during the simulation.
•   In order to use the extractData script, you will need to save the log file of the simulation.
•   At this point, we are ready to run the simulation.
•   We will use the solver interFoam.
•   You will find the instructions of how to run the cases in the file README.FIRST located in the
    case directory.
                                                                                                     965
                 Roadmap
                                          966
             A crash introduction to source terms OpenFOAM®
                                                                                                     967
             A crash introduction to source terms OpenFOAM®
Set of cell
Point selection
                                                                                                     968
             A crash introduction to source terms OpenFOAM®
23       }
                                          •   Remember, you can use the banana method to know all
24   }                                        source terms and options available.
                                          •   You can also read the source code.
                                                                                                         969
                  Source terms hands-on tutorials
$PTOFC/advanced_physics/source_terms/filter/porous_source
•   In the case directory, you will find the README.FIRST file. In this file, you will find the general instructions of
    how to run the case. In this file, you might also find some additional comments.
•   You will also find a few additional files (or scripts) with the extension .sh, namely, run_all.sh,
    run_mesh.sh, run_sampling.sh, run_solver.sh, and so on. These files can be used to run the case
    automatically by typing in the terminal, for example, sh run_solver.
•   We highly recommend to open the README.FIRST file and type the commands in the terminal, in this way
    you will get used with the command line interface and OpenFOAM® commands.
•   If you are already comfortable with OpenFOAM®, use the automatic scripts to run the cases.
                                                                                                                      970
                Source terms hands-on tutorials
                                       Filter source term
•   In this case we are going to use the source term explicitPorositySource.
•   Using this source term we can apply a porous region (e.g., Darcy-Forchheimer) in the cell
    selection.
•   The source term is activated after 2 seconds of simulation time.
                Set of cell
                 (filter)
                                                      http://www.wolfdynamics.com/training/sourceterms/image1.gif   971
                Source terms hands-on tutorials
                                            Filter source term
             system/fvOptions
                                                    •   The source terms can be selected in the
17
18
     filter1
     {
                                                        dictionary fvOptions, and they can be modified
19       type explicitPorositySource;                   on-the-fly.
20       active          yes;
22       explicitPorositySourceCoeffs               •   In this case we are using the source term
23       {
25           timeStart        2;                        explicitPorositySource (line 19).
26           duration         5;
28           selectionMode    cellZone;             •   Using this source term we can apply a porous
29           cellZone         filter;                   region (of the type Darcy-Forchheimer) in the cell
31           type             DarcyForchheimer;
                                                        selection (line 28).
38           DarcyForchheimerCoeffs
39           {                                      •   The source term is used in a cellZone (line 28)
41
44
                 d
                 f
                       (5000000 5000000 5000000);
                       (0 0 0);
                                                        named filter (line 29), this zone must be created
46               coordinateSystem                       at meshing time or using the utility topoSet.
47               {
49                   type      cartesian;           •   In lines 38-60, we define the input parameters of
50                   origin (0 0 0);
52                   coordinateRotation
                                                        the model.
53                   {
54                        type     axesRotation;
                                                    •   In this case, the coefficients f and d are
55                        e1 (1 0 0);                   resistance/impermiability coefficients, and e1 and
56                        e2 (0 1 0);
57                   }
                                                        e2 are the vectors that are used to specify the
59               }                                      porosity.
60           }
61       }
62   }
                                                                                                        972
                   Source terms hands-on tutorials
                                             Filter source term
            system/topoSetDict
                                                   •   To create the cellZone used in fvOptions, we
                                                       first create a cellSet.
                                                   •   The set of cells (cellSet) is constructed using the
                                                       utility topoSet.
                                                   •   This utility reads the dictionary topoSetDict,
                                                       which is located in the directory system.
                                                                                              974
             Source terms hands-on tutorials
                                  Filter source term
                                                                                       975
                 Roadmap
                                          976
                          Scalar transport pluggable solver
                                                                                                      977
                           Scalar transport pluggable solver
enabled true;
    writeControl outputTime;
                                                                  Number of corrector iterations.
    log yes;                                                      It is recommended to do t least one iteration.
    nCorr 1;
                                                                  Diffusion coefficient.
    D 0;                                                          If turbulent modeling is in use, you can define the
    //alphaD 0;                                                   laminar diffusion coefficient alphaD and the turbulent
    //alphaDt 0;                                                  diffusion coefficient alphaDt
Boundary conditions
                        0/s1
                                                 •   Assuming that you named the new scalar s1, you
dimensions           [0 0 0 0 0 0 0];                will need to define the boundary conditions and
                                                     initial conditions for the field s1.
internalField        uniform 0;
                                                 •   This is done in the dictionary 0/s1.
boundaryField
{                                                •   In this case, the scalar is entering in the patch
  walls
  {                                                  inlet with a value of 1 (this is a concentration
      type                zeroGradient;              therefore it has no dimensions).
  }
    inlet
                                                 •   The initial concentration of the scalar is zero.
    {
        type              fixedValue;
        value             uniform 1;
    }
    outlet
    {
        type              inletOutlet;
        inletValue        uniform 0;
        value             uniform 0;
    }
}
                                                                                                         979
                          Scalar transport pluggable solver
system/fvSchemes system/fvSolution
    gradSchemes                                                s1
    {                                                          {
        default      Gauss linear;                                  solver       smoothSolver;
        grad(s1)     cellLimited Gauss linear 1;                    smoother     symGaussSeidel;
    }                                                               tolerance    1e-08;
                                                                    relTol       0;
                                                               }
    divSchemes
    {
        default     none;
        div(phi,U) Gauss linearUpwindV default;
        div(phi,s1) Gauss vanLeer;
    }
                                                                                                     980
    Scalar transport pluggable solver hands-on tutorials
$PTOFC/advanced_physics/source_terms/2Delbow_passive_scalar
•   In the case directory, you will find the README.FIRST file. In this file, you will find the general instructions of
    how to run the case. In this file, you might also find some additional comments.
•   You will also find a few additional files (or scripts) with the extension .sh, namely, run_all.sh,
    run_mesh.sh, run_sampling.sh, run_solver.sh, and so on. These files can be used to run the case
    automatically by typing in the terminal, for example, sh run_solver.
•   We highly recommend to open the README.FIRST file and type the commands in the terminal, in this way
    you will get used with the command line interface and OpenFOAM® commands.
•   If you are already comfortable with OpenFOAM®, use the automatic scripts to run the cases.
                                                                                                                      981
    Scalar transport pluggable solver hands-on tutorials
                  Scalar transport in an elbow – Internal geometry
•   Notice that we are adding two scalars, s1 and s2.
S1
U → (2 0 0)
                                                   http://www.wolfdynamics.com/training/sourceterms/image2.gif
                          S2
                          U → (0 3 0)
                                                   http://www.wolfdynamics.com/training/sourceterms/image3.gif   982
    Scalar transport pluggable solver hands-on tutorials
                   Scalar transport in an elbow – Internal geometry
•   At this point, we are ready to run the simulation.
•   We will use the solver pisoFoam.
•   Remember to adjust the numerics according to your physics.
•   Do not forget to create the boundary conditions and initial conditions of the new field variables.
•   You will find the instructions of how to run the cases in the file README.FIRST located in the
    case directory.
                                                                                                     983
                   This is the end