{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# CFD Simulation Case Setup\n", "\n", "**The created CFD domain is now read into the CFD package of interest to setup the CFD simulation. It should be noted that the current tutorial has a significant difference compared to other available CFD tutorials online! This tutorial is structured and developed based on a generic and methodological approach to set up a CFD simulation. The first principals and reasonings for each setting is discussed at each step. Potential alterations and modifications to perform similar analysis for different flow conditions are also addressed and discussed. Hence, in the end user will have the capability of applying potential modifications, improvements or extending the application of the current CFD simulation to a more complex problem of interest, rather than having a one time successful run of a specific simulation with specific and strictly pre-defined boundary conditions.**\n", "\n", "> **_In simple words: Current tutorial teaches users to fish, rather than giving them a fish._**\n", "\n", "## Setting up a CFD simulation has following four steps:\n", "\n", "**0. Import the CFD Domain into Solver:**\n", "\n", "The previously generated CFD domain, fully explained in the Domain section, will be imported properly into the CFD solver.\n", "\n", "**1. Setup Model/s:**\n", "\n", "According to the physics of the flow field user will select required model/s to simulate the flow.\n", "\n", "**2. Setup Working Fluid/s & Solid/s:**\n", "\n", "User will define the physical and thermodynamical properties of the working fluid/s and solid/s in the problem. \n", "\n", "**3. Setup Boundary & Zone Conditions:**\n", "\n", "Solving the governing equations of the flow (i.e. system of partial differential equations) requires well-defined boundary conditions within the CFD domain. These conditions are selected and defined in this step.\n", "\n", "**4. Setup Solution Methods:**\n", "\n", "In CFD simulations the governing equations of the flow are solve numerically. Based on the physics of the problem appropriate numerical schemes and solution methods are selected at this step.\n", "\n", "In the following section the details for the above-mentioned four steps of the CFD simulation setup process for the case study of **2D Laminar Flow Over a Rotating Cylinder** are explained in great details. As a general guideline, to setup a CFD simulation in OpenFoam it is recommended to start with files from one of the provided default tutorials in OpenFoam located in `OpenFoam/run/tutorials`. Users should find appropriate tutorial such that the general physics of the chosen tutorial is close to the problem of interest of users. This way, the majority of the required physical settings are pre-set and the others can be changed/modified accordingly. For example for the problem of **2D Laminar Flow Over a Rotating Cylinder** the tutorial of **Fluid flow over a 2D backward facing step** located at `OpenFoam/run/tutorials/incompressible/pimpleFoam/pitzDaily` is used. Using the previously developed file, the above-mentioned four steps for CFD simulation development is done via editing the corresponding files, where the settings are defined and are located in the main working directory.\n", "\n", "**0. Importing the Created CFD Domain into Solver:**\n", "\n", "The official mesh generator for OpenFoam is called `blockMesh`. This is a command base mesher software. Users write/edit the desired settings to generate and discretize the geometry of CFD domain in a dictionary file (i.e. a text file) named `blockMeshDict` located at `\\system` inside the main working directory. In previous versions of OpenFOAM (earlier than v3.0.0), the `blockMeshDict` file was located at `\\constant\\polyMesh` directory. In simple words the file is the dictionary, where the geometry and discretization process of it are fully defined. Once edits of `blockMeshDict` file are completed then it is compiled via the command `blockMesh`. This will generate multiple required files, that include the details of the discretized CFD domain for the use of OpenFoam solver in `\\constant\\polyMesh` directory. In this tutorial this utility is used to produce the required mesh. Users should make sure that the generated report contains no error or problem after running the command. The details of the previously generated CFD domain by `blockMesh` are fully explained in the Domain (see Open_Foam -> Domain) part of this tutorial.\n", "\n", "Alternatively, OpenFoam has various built-in commands that allow it's users to convert their previously generated CFD domain in different mesher packages into the readable format for the OpenFoam. Users can use the available * .msh file, which was generated previously in another mesher, in the Simulation_Src directory and use the command fluentMeshToFoam with the name of the mesh file after the command to perform the mesh conversion process (i.e. fluentMeshtoFoam $[file name].msh$). Running this command will generate multiple required files, that include the details of the discretized CFD domain for the use of OpenFoam in the working directory. This is identical to running `blockMesh` command and compiling the previously defined `blockMeshDict` file. Users should make sure that the generated report contains no error or problem. A list of these commands can be found [here](http://www.openfoam.org/features/mesh-conversion.php).\n", "\n", "**1. Setup Model/s:**\n", "\n", "In case of fluid flow over a cylinder, various fluid patterns may occur based on the Reynolds number. For Re ~< 47 the fluid flow around cylinder is maintained symmetrical and no vortex shedding happens. This state is considered as being steady and therefore a steady time scheme is required to model the problem. Further, by increasing Reynolds number the fluid flow starts to oscillate behind the cylinder and vortex shedding will begin to happen. Because of this transient behavior of the flow, a suitable transient time scheme has to be chosen to develop the CFD simulation This along with other numerical schemes settings are set in a dictionary file called \"fvSchemes\" located at `\\system` folder. Various available time schemes along with other implementable option within \"fvSchemes\" dictionary file in OpenFoam can be found [here](http://cfd.direct/openfoam/user-guide/fvschemes/). To set the solver to be transient, users define `Euler` for the `ddtSchemes` and the rest of the settings will remain unchanged:\n", "\n", "```C++\n", "ddtSchemes\n", "{\n", " default Euler;\n", "}\n", "```\n", "\n", "In the current problem the focus is to investigate laminar wake and boundary layer behavior when a uniform flow passes over a rotating cylinder. The appropriate model for this problem is set in a dictionary file called `RASPropertise` (RAS stands for Reynolds Averages Stress) located at `\\constant` folder. This is done by choosing the `laminar` dummy turbulence model as the value for `RASModel` keyword.\n", "\n", "```C++\n", "RASModel laminar;\n", "\n", "turbulence off;\n", "\n", "printCoeffs off;\n", "```\n", "\n", "It is important to note that the critical Reynolds number for turbulent flows over a cylinder is about $10^5$. In cases that the Reynolds number, based on cylinder diameter (as the length scale), is greater than this critical value the appropriate turbulent model should be selected at this step. Various available turbulence models along with other options within `RASPropertise` dictionary file in OpenFoam can be found [here](http://cfd.direct/openfoam/user-guide/turbulence/).\n", "\n", "**2. Setup Working Fluid/s & Solid/s:** \n", "\n", "The choice of working fluid is problem dependent. In the absence of obligations to define a specific working fluid such as air or water, it is suggested that the users define the working fluid such that the important non-dimensional groups of interest, such as Reynolds number in this problem, is matched the desired flow conditions. This strategy removes the uncertainty in the choice of the working fluid and will solidify the bases for expected physical observations. The material properties in OpenFoam can be defined in a dictionary file `transportPropertise` located in `constant` folder. In this file the material is set to be `Newtonian` fluid with a defined kinematic viscosity $\\nu$. It should be noted that the numbers in the [] set the dimension of the flow field variable of interest and the other number sets it's value:\n", "\n", "```C++\n", "transportModel Newtonian;\n", "\n", "nu nu [ 0 2 -1 0 0 0 0 ] 0.01;\n", "```\n", "Considering that the cylinder diameter is 1 [m] and user will define a unit constant uniform velocity (1 [m/s]), the value of $\\nu$ will be defined as the inverse of Reynolds number. Therefore, changing this value would set the nominal Reynolds number of the flow based on the cylinder diameter. For other cases users should define the working fluid via this process. Various available transport models along with other options within `transportPropertise` dictionary file in OpenFoam can be found [here](http://cfd.direct/openfoam/user-guide/transport-rheology/#x40-2210007.3.1).\n", "\n", "**3. Setup Boundary and Zone Conditions:** \n", "\n", "In OpenFoam the type of basic boundaries within the CFD domain are defined in the `boundary` file located at `\\constant\\polyMesh`. Whether the users use blockMesh or the convert command to create the CFD domain, the `boundary` file will be created in this process. These basic boundary conditions were previously set in `blockMeshDict` file. Furthermore, values for the field variables, such as velocity **U** and pressure **p**, at these boundaries are set in `U` and `p` files located at `0` folder located in the working directory respectively. The `0` folder includes the values of the field variables at boundaries for the time `t=0`.\n", "\n", "As discussed earlier in the CFD domain's creation and discretization section, the CFD domain has four faces as boundaries. The boundary and zone conditions settings to develop CFD simulation for **2D Laminar Flow Over a Rotating Cylinder** case in OpenFoam are as follows:\n", "\n", "**Inlet:** The flow enters from the inlet face of the CFD domain with constant velocity and uniform atmospheric pressure (i.e. zero gauge pressure). Set the field variables at this boundary by editing `U` and `p` files in `\\0` folder to a constant uniform velocity in the streamwise direction (x-direction) with zero pressure gradient:.\n", "\n", "```C++\n", "// In U file at 0 folder:\n", "inlet\n", "{\n", " type fixedValue;\n", " value uniform (1 0 0);\n", "}\n", "\n", "// In p file at 0 folder:\n", "inlet\n", "{\n", " type zeroGradient;\n", "}\n", "```\n", "\n", "**Outlet:** The flow exits the CFD domain from the outlet and top face of the domain and reaches atmospheric pressure (i.e. zero gauge pressure). Set the field variables at this boundary by editing `U` and `p` files in `\\0` to a constant uniform atmospheric pressure with zero velocity gradient:\n", "\n", "```C++\n", "// In U file at 0 folder:\n", "outlet\n", "{\n", " type zeroGradient;\n", "}\n", "\n", "// In p file at 0 folder:\n", "outlet\n", "{\n", " type fixedValue;\n", " value uniform 0;\n", "}\n", "```\n", "If in a problem of interest, there exist a specific pressure difference between the inlet and outlet or other surfaces, that magnitude can be defined in corresponding faces of the domain.\n", "\n", "**frontAndBack:** Since this problem is two dimensional the boundary type of the flow field variables for the `frontToBack` boundary, which defines the third dimension of the flow field are set to `empty`:\n", "\n", "```C++\n", "// In U and p files at 0 folder:\n", "frontAndBack\n", "{\n", " type empty;\n", "}\n", "```\n", "\n", "**Cylinder:** The flow passes over the rotating cylinder located in the middle of the CFD domain. One of the most important physical phenomena to implement here is that while the flow is interacting with the walls of the cylinder based on the \"no-slip\" boundary condition, the wall of the cylinder should rotate as well. In order to impose these two boundary conditions at the same time the `rotatingWallVelocity` as type of boundary is imposed to the cylinder wall. For this boundary type, an angular velocity `omega` for the cylinder rotation and a flow velocity `value` on the as no-slip condition are imposed on wall of the cylinder. \n", "\n", "Set the field variables at this boundary edit \"U\" and \"p\" files in `\\0` to a fixed rotating value with zero pressure gradient:\n", "\n", "```C++\n", "// In U file at 0 folder:\n", "cylinder\n", "{\n", "\ttype\t rotatingWallVelocity;\n", "\torigin\t\t(0 0 0);\n", "\taxis\t\t(0 0 1);\n", "\tomega\t\t2;\n", "\tvalue\t\tuniform (0 0 0);\n", "}\n", "\n", "// In p file at 0 folder:\n", "cylinder\n", "{\n", " type zeroGradient;\n", "}\n", "\n", "```\n", "\n", "If the shear forces and formed boundary layer becomes turbulent in this region user should modify this boundary conditions and provide required mesh resolution to capture the phenomena or set this boundary to free slip condition such that fluid elements would not interact with wall region. For low Reynolds number flow, similar to the current problem of interest, a reasonable mesh resolution is sufficient to capture the laminar boundary layer region.\n", "\n", "For more detail on definitions and settings for defining CFD domain boundary conditions in OpenFoam readers are referred to [here](http://cfd.direct/openfoam/user-guide/boundaries/).\n", "\n", "**4. Setup Solution methods:** \n", "\n", "In this step, it is highly recommended to use the default/suggested solution methods set in `fvSolution` file located in `\\systems`, unless based on physics of the problem the user is aware of any specific choices. Upon non-smooth convergence and potential divergence of the CFD simulation user can modify and examine various solution methods. The `fvSolution` file includes the solution methods for velocity and pressure fields and the required under relaxation factors for flow field variables.\n", "\n", "Now all boundary conditions and settings for the CFD simulation are fully defined. User can **initialize** the solution through an educated guess to start the iteration process. In OpenFoam the initialization of the velocity and pressure fields is set on top of the `U` and `p` files located in the `0` folder:\n", "\n", "```C++\n", "// In U file at 0 folder:\n", "internalField uniform (1 0 0);\n", "\n", "// In p file at 0 folder:\n", "internalField uniform 0;\n", "```\n", "The solution initialization would incept the flow field variables, such as velocity and pressure, based on the defined values by user. For the current problem the CFD domain is recommended to be initialize by values of velocity and pressure at the inlet.\n", "\n", "Iteration process for solving the flow field governing equation now shall start till converged solution is obtained. In OpenFoam the iteration can initiated by running a command line using the name of the application of choice. The name of the application and value of marching time steps to solve the flow field governing equations are set in `controlDict` dictionary file located in `\\system` directory:\n", "\n", "```C++\n", "application pimpleFoam;\n", "\n", "startFrom latestTime;\n", "\n", "startTime 0;\n", "\n", "stopAt endTime;\n", "\n", "endTime 150;\n", "\n", "deltaT 0.01;\n", "\n", "writeControl runTime;\n", "\n", "writeInterval 0.5;\n", "```\n", "For this problem 150 seconds of run time is set with time steps of 0.01 seconds. The outputs will be written every 0.5 second till the end of the run time. It should be noted that these are the corresponding settings for case study with Reynolds number of 100 and Tip Speed Ratio ($TSR=\\frac{R*\\omega}{U_0}$) of 1, where time step size of 0.01 s is small enough to correctly capture the flow fields in the domain. Users can change the length of the time interval and time steps according to the physics of the flow field and numerical simulation requirements. \n", "\n", "Before start running simulation one additional step for simulation setup should be taken. This is the step of setting up drag force coefficient calculation on the cylinder and reporting it at every single iteration. As discussed earlier in the theory section according to dimensional analysis of flow over a cylinder, Reynolds number and drag force coefficients are the two non-dimensional variables that describe the physics of this problem. Therefore, monitoring the convergence trend of this these two variables is vital. To calculate and report the drag force coefficient for flows with different Reynolds number in every single iteration, user can take advantage of pre-defined functions and libraries developed in OpenFOAM. One can simply add the following force calculation function into the end of the `controlDict` dictionary file located in `\\system` directory as follows:\n", "\n", "```C++\n", "functions\n", "{\n", "\n", " forcesCoeffs\n", " {\n", "\t type forceCoeffs;\n", "\n", "\t functionObjectLibs ( \"libforces.so\" );\n", "\n", "\t outputControl timeStep;\n", "\t timeInterval 10;\n", "\n", "\t log no;\n", "\n", "\t patches ( cylinder );\n", "\t pName p;\n", "\t UName U;\n", "\t rhoName rhoInf; // Indicates incompressible\n", "\t log true;\n", "\t rhoInf 1; // Redundant for incompressible\n", "\t liftDir (0 1 0);\n", "\t dragDir (1 0 0);\n", "\t CofR (0 0 0); // Axle midpoint on ground\n", "\t pitchAxis (0 0 1);\n", "\t magUInf 1;\n", "\t lRef 1; // Wheelbase length\n", "\t Aref 1; // D * Domain_Thickness\n", " }\n", "}\n", "```\n", "\n", "This function is called `forceCoeffs`. User defines `cylinder` walls as the patch to calculate the forces on, in the defined directions. The three available directions are `liftDir`, `dragDir` and `pitchAxis`. Based on the orientation of coordinates in the current CFD-domain the drag force direction is along x-axis (1 0 0), the lift force direction is along y-axis (0 1 0) and `pitchAxis` is along z-direction (0 0 1). The center of origin called `CodR` is located at (0 0 0). The other inputs for this function are reference values for velocity, density, diameter and area used to normalize the drag force to calculate the drag coefficient. Usually the values for these variables are defined as the free stream flow properties. In this case study reference values of velocity, density, diameter and area are all equal to 1. It should be pointed out that the value of density is redundant in incompressible solvers since the flow field governing equations (i.e. Reynolds Averaged Navier-Stokes equations) in this solver are normalized by the density, hence the calculated and reported force value is normalized by density value.\n", "\n", "Fundamentally, the reference area to calculate the drag force coefficient is defined as the total \"effective\" area that the force of interest is acting against. In case of the flow over a cylinder the fluid forces on the body of cylinder can be visualized as shown in the Fig. 1:\n", "\n", "\n", "Fig.1 - Schematic of total fluid force and it's decomposition on the body of cylinder.\n", "\n", "Each force component can be decomposed into two components in the horizontal and vertical directions shown with red and green colors respectively. Due to the symmetry of the geometry the vertical components of the forces cancel each other. Therefore, the total drag force is the summation of all horizontal forces that are acting against the projected area along the cylinder's wall as visualized in the zoom-in view of Fig. 1. This area is defined as the reference area `Aref` and is equal to diameter times the depth of the cylinder. For the current CFD domain the diameter is 1 [m] and the created depth of the mesh via \"blockMesh\" is also 1 [m]. Therefore, the value of the reference area is 1 $[m^2]$. Note that for a purely 2D problem (with no depth in mesh) the value of depth is considered to be unity. Therefore, in that case the value of the reference area is also 1 $[m^2]$\n", "\n", "At this stage the iterations for this simulation can be started by running the command `pimpleFoam`. To get outputs of residuals it is better to run the command `foamJob -s pimpleFoam` to save the residual values and plot them later. This command stores history of all residuals in a file called `log` in the main case directory and at the end of simulation, running the command `foamLog logs` will extracts the residuals data sets in a directory called `logs`." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.5.1" } }, "nbformat": 4, "nbformat_minor": 0 }