Post‐Processing Results with ParaView and OpenFOAM functionObjects ‐ no figures - openfoam-ICL-UC/openfoam_intro_EN GitHub Wiki
Tutorial: Post-Processing Results with ParaView and functionObjects
In this tutorial, you will learn how to use ParaView to post-process simulation results obtained with OpenFOAM. These skills will be transferable to any object that can be saved in .VTK format. Additionally, you will learn basic principles to improve the quality of your illustrations. To post-process a simulation case, you need results to post-process. These results will be those obtained during Day 1 for the 3-D heat convection in an unsteady state in a circular pipe.
1. Running the tubeConv Case
First, make sure you have the repository on your Linux system, Windows Subsystem for Linux, or Docker. To do this:
- If you have GitHub, go to the repository's main page, click the green "code" button, and clone the repository with the command
git clone [repository link]. - If you don't have GitHub, go to the same page, click the green button, and then select "Download as .zip". This will download a compressed file with the repository's contents. Once the download is complete, extract the contents of the repository, which will likely create a folder. Inside that folder, you will find another folder with the repository's content. Now you need to move the contents of that folder to the default directory that opens in Windows Subsystem for Linux.
- To find the default directory, open WSL and type
pwd. This will print the path to your default Linux folder. - Move the repository folder to the default Linux folder. To do this, click on the file explorer, then click on the "Linux" or "Ubuntu" drive in the left sidebar, which should appear with a penguin icon. This will open the Linux root folder, and from there you can navigate to the default Linux folder. Once you find that folder, copy and paste the repository folder into it.
If you participated in session 1.2 of the workshop, you have probably already done these steps.
To verify that the repository copy was successful, open WSL and enter the command ls. The openfoam_intro_ES-main or openfoam_intro_ES folder should appear. Navigate to that directory using the cd command, which allows you to change directories:
cd openfoam_intro_EN
Once in the directory, access the openfoam workspace, navigate to the tubeConv directory, and generate the mesh using the following commands:
openfoam2406
cd cases/Day-1/Part_1.2_tubeConv
blockMesh
To run the simulation, you have two options. The first is to run the solver and save the simulation output text with the following command:
buoyantBoussinesqPimpleFoam > b.log &
The second option is the "standard" way to run OpenFOAM cases. This involves converting the Allrun file into an executable and then running it. A file is executable if it appears in green when you type ls. If it appears in white or you have doubts, you can convert the Allrun file into an executable and run it with the following commands:
chmod +x Allrun
./Allrun
You can examine the contents of the Allrun script. You will note that a decomposePar statement is present. This decomposes the domain in $np$ processors. The dictionary that controls and configures the decomposition can be found in system/decomposeParDict. We left a default number of 4 processors, as most laptops nowadays have 4 processors. The decomposition occurs in the axial direction. The idea of the domain decomposition is to accelerate the simulation, having each processors to work only in a fraction of the original domain. This can accelerate convergence in each core, however, there is an additional simulation time to coordinate all processors traditionally known as intercommunication overhead. This tend to be an issue in complex domains or a very large number of processors.
The simulation will run for 60-120 seconds. Once the simulation is finished, the solution will be stored in 24 time steps, ranging from 0.5 to 12 seconds spaced by 0.1 seconds. To post-process the solution, you need to create an empty foam.foam file:
touch foam.foam
Congratulations! You have completed the preliminary steps for post-processing.
2. Post-Processing in ParaView
Open the foam.foam file with ParaView from the command line:
paraview foam.foam
ParaView will open, and in the left navigation menu, a file with your simulation results will appear. Click the "Apply" button.
Clicking the "Apply" button will show a small "circle." This corresponds to the front view of the cylinder where natural and forced convection was solved. The colors show the values of dynamic pressure on this boundary, $p' = p/\rho$, since they come from a solver for incompressible fluid in OpenFOAM.
The user interface has a series of buttons that control the visualization. From the top bar menu, we will primarily use the File, View, and Filters menus.
2.1 Examining Scalar and Vector Property Profiles
In the third bar from the bottom up, you will find a dropdown menu to access scalar and vector fields in the solution domain.
"Point" and "Cube" Profiles
Clicking the dropdown menu will display a list with the fields repeated twice: first with a "point" icon and then with a "cube" icon. The "point" option shows the interpolated field values on the faces of the control volume. This option is often more aesthetically pleasing but involves a transformation of the original results obtained in OpenFOAM. On the other hand, the "cube" option shows the field value at the center point of the control volume. These values are directly stored in OpenFOAM.
2.2 Filters
2.2.1 Calculator: Calculating Arithmetic Properties from Available Fields
Often, the default image doesn't provide much useful or interesting information directly. For this, you can apply filters to the image to calculate various types of quantities of engineering interest. For example, let's imagine we want to calculate the thermal energy flux transported by convection:
$$ F_{conv} = \rho \hat{c}_p T \mathbf{v} $$
To do this, we can use the Calculator filter, name the quantity "F_e":
You can apply new filters on top of previous filters or apply filters from the original results. For the latter, select the foam.foam file again from the Pipeline Browser, and also click the "eye" near Calculator1 to stop showing the thermal energy flux calculation results.
2.2.2 Contour: Contour Plot
The Contour filter allows plotting contour lines and observing how they change over time. This generates "iso-surfaces" that show the region of the domain at a specific temperature over time. We can apply the Contour filter to examine how the temperature of the tube evolves radially.
- Click on foam.foam
- Select the temperature field, "T," to visualize the temperature.
- Click on
Filters > Common > Contour - Select
Contour ByT and remove the default value inIsosurfaces - Add the values 70, 71, 72, 73, 74, 75 to
Isosurfaces: - Click "Apply" and several layers will appear near the walls for the time "Time 0.1".
- Press the "Play" button to see how the surfaces move inward and towards the entrance.
The figure should shows the contour plots or iso-surfaces of temperature after 6 seconds into the simulation. The results clarify the spatial evolution of the temperature profile over time.
2.2.3 Clip: Defining Subsets of the Domain
The Clip filter allows cutting the results to a region of interest defined by the end or beginning (Invert option) of the coordinate system. For example, if we wanted to plot the section of the pipe within the first half of the inlet length, $0 \leq z \leq 5D$:
-
Click on foam.foam
-
Click on
Filters > Common > Clip -
Click on the "Z Normal" button in the properties folder to generate a plane normal to the axial axis of the pipe.
-
Specify the origin of the normal vector at the point $(x, y, z) = (0, 0, 0.25)$
-
Click on the "Invert" option to select the interval between the origin of the coordinate system and the origin of the normal vector.
-
Click on the Apply button to apply the filter
-
Uncheck the "Show Plane" box in Plane Parameters to stop displaying the plane.
-
Click on the Reset button, with two crossed diagonal arrows, to adjust the visualization
-
Navigate in the Properties menu to select the "Data Axes Grid" button to display the coordinates of the parallelepiped containing the clipped domain.
2.2.4 Slice: Defining Subsets of the Domain
The Slice filter reduces the dimensionality of the visualization by intersecting a plane with the domain. This is very useful for visualizing profiles with some type of symmetry. Assuming there is angular symmetry in the heat convection in a 3-D pipe, it is interesting to explore the temperature and velocity profiles in two planes.
First, we will cut the pipe with a plane at a fixed angle. Since Paraview has a Cartesian coordinate system by default, this will be represented as a plane normal to either the x or y coordinate. If there is angular symmetry, either of these planes will give an equivalent profile. We will cut the pipe with a plane normal to the x-axis:
- Remove other existing filters from the Pipeline Browser, except foam.foam
- Click on foam.foam, select in Mesh Regions
internalMeshand in Cell Arrays, all variables. Then click on the top menu: Filters > Common > Slice. - The default plane will be normal to the x-axis. This can be seen in the Properties menu, which has a normal vector $\hat{n} = (1, 0 ,0)$.
- Uncheck the "Show Plane" box and then click Apply.
- To get a clear view of the system, click on the +X button in the third menu, and then rotate the domain 90 degrees to the right:
You will visualize the geometry of the pipe and the temperature profile in colors.
If you click "Play" you will see the evolution of temperature inside the pipe. At the end of the simulation, it is observed that near the entrance the temperature is minimal, and as the flow circulates the thermal boundary layer develops.
Since the wall temperature is substantially higher than in the rest of the domain, the temperature scale obscures the temperature increase along the z-axis. To correct this, we look in the Properties menu for the Coloring section, and then click on the "c" button with two arrows. This allows entering a custom temperature range. We choose 70-72 as a custom range, and then observe how the profile changes.
Since the wall temperature is substantially higher than in the rest of the domain, the temperature scale obscures the temperature increase along the z-axis. To correct this, we look in the Properties menu for the Coloring section, and then click on the "c" button with two arrows. This allows entering a custom temperature range. We choose 70-72 as a custom range, and then observe how the profile changes.
The obtained profile is visually more attractive and allows observing the axial evolution of temperature more clearly. However, it does not provide the actual wall temperature value.
2.2.5 Glyph: Velocity Profile Plot
This view is very useful for visualizing velocity profiles. To do this, we will use the Glyph filter on the Slice filter.
-
Click on Pipeline Browser > Slice1
-
Click on Filters > Common > Glyph
-
In Properties, select Orientation Array > U. This will generate arrows representing the velocity vector at each point.
-
Optionally, you can select the U field in Scale Array, and then choose Scale by Magnitude.
-
If desired, "unselect" the Slice view from the Pipeline Browser to stop seeing the temperature profile.
-
Zoom into the inlet region, where you will find a piston flow profile.
-
Move to the pipe outlet by dragging the image to the right with the mouse to visualize the development of a turbulent profile that seems to follow the 1/7 law.
2.2.6 Plot over line: Defining Subsets of the Domain
Imagine that we want to verify the axial velocity as a function of radius at different points in the pipe: at an inlet region $z_1 = 0.25 m$, and at the pipe outlet, $z_2 = 1 m$. Let's start with $z_2$:
-
Click on Pipeline Browser > foam.foam.
-
In Mesh Regions, select only patch/outlet
-
Click on Filters > Data Analysis > Plot Over Line
-
In Line Parameters, enter the coordinates of two points of a line that crosses from $-r$ to $r$. For example,
-
Click Apply
-
Scroll down to Series Parameters, and select only axial velocity, U_Z, in the y-axis. The z-axis shows a coordinate that is $0$ at $r = -R$ and $2R$ at $r = R$.
-
Note the emergence of a pseudo-parabolic profile, with a linear gradient near the walls showing the effect of the boundary layer.
-
To find the profile at $z = 0.25m$, first click on Pipeline Browser > foam.foam, select the internalMesh region under Mesh Regions and click Apply.
-
Then click on PlotOverLine1 in the Pipeline Browser, change the z-coordinate of the normal vector to 0.25, and click Apply.
A velocity profile similar to what would be expected from turbulent flow following the 1/7 law will appear, with a large velocity gradient near the walls and a nearly constant velocity flow further away.
2.2.6 Integrate Variables + PlotDataOverTime
The first filter calculates average properties in volumes and surfaces of interest. The second filter calculates the temporal evolution of a variable. The combination of both filters allows finding the temporal evolution of an average quantity, which is usually relevant for macroscopic property balances.
For example, if we want to calculate the average temperature at the pipe outlet over time, we do the following:
-
Click on Pipeline Browser > foam.foam
-
Select exclusively
patch/outletunder "Mesh Regions," temperatureTunder Cell Arrays, and click "Apply". -
Click on Pipeline Browser > foam.foam again
-
Click on Filters > Data Analysis > IntegrateVariables.
-
Check the "Divide Cell data By Volume" box in Properties, and then click Apply.
-
In the window on the right, select the dropdown menu to the right of "Attribute" and change "Point" to "Cell".
-
Click on the cell where the temperature appears at the top right.
-
Click on Filters > Data Analysis > Plot Data Over Time, then in the Field Association dropdown mark Cells, and finally press the Apply button.
-
A graph will appear on the right where the average temperature is not very visible. Go to Series Parameters and uncheck the box near the Area (stats) variable. This will improve the aesthetics of the graph showing the evolution of average temperature at the pipe outlet over time.
FunctionObjects for Calculating Engineering Quantities in OpenFOAM
Calculation of Heat Flux through Walls
The heat flux entering through the walls of the pipe is defined as
$$ \dot{Q_w} = \int_S - (\hat{\mathbf{n}} \cdot \mathbf{q}) dS = \int_S (\mathbf{n} \cdot k \nabla T) dS $$
where ( k ) is the thermal conductivity of the fluid circulating inside the wall.
The calculation of heat flux can be performed in three main steps:
- Calculate the temperature gradient on the wall using a functionObject in the system/controlDict dictionary.
- Integrate the dot product between the temperature gradient and the normal vector on the surface.
- Reconstruct the heat flux by multiplying the temperature gradient by the effective thermal conductivity, $ k_{eff} = k + k_t = 0.16 W/mK + 0.9 W/mK = 1.16 W/mK $.
To accomplish this, it is necessary to incorporate two functionObjects into the functions dictionary in the file system/controlDict. The following code shows the implementation of the OpenFOAM functionObjects:
functions
{
gradT
{
// Mandatory parameters
// Object name
type grad;
libs (fieldFunctionObjects);
// Dependent variable to apply the functionObject
field T;
// Resulting field name after applying the object
result gradT;
// Default region0 setting
region region0;
// Generate a gradT field for each temperature
writeControl writeTime;
}
dTdn
{
// Object name
// surfaceFieldValue allows arithmetic operations
// with scalar fields
type surfaceFieldValue;
// Standard
libs (fieldFunctionObjects);
// Write the results of the integral operation
// for each stored time
writeControl writeTime;
// Log the results into a file
// within the postProcessing folder
log yes;
// Do not save the fields
writeFields no;
// Region type: in this case,
// it is a patch because the integral
// is performed over a boundary
regionType patch;
// Boundary name: walls, representing
// the pipe wall. This must be consistent
// with the names in the constant/polyMesh folder
name walls;
// This operation, within surfaceFieldValue,
// integrates the dot product between the
// vector field and the surface normal vector
operation areaNormalIntegrate;
fields
(
// temperature gradient vector
gradT
);
}
}