Kinetic energy Analysis with Heat flux Post-processing Turbulence and Reynolds - utilizes a compressible turbulent slice of the US3D CFD data outputted from ITKIT, then analyzes the Reynolds shear stress, normal stress, wall heat flux, and the turbulence kinetic energy budget. The output is presented in Tecplot formatting.
Explore the GitHub Repo »
Read the Independent Study »
Report Bug
·
Request Feature
·
Pull Request
·
Change Log
·
Citation
·
Contributing
·
Code of Conduct
Table of Contents
The aim of this independent study was to implement a C++ script similar to ITKIT, where the program is easily integrated into CU research computing and can function harmoniously with US3D and ITKIT on behalf of Dr. Macdonald's research group. The program will consider data from a compressible turbulent slice of the CFD data outputted from ITKIT, then analyze the Reynolds shear stress, Reynolds normal stress, wall heat flux, and the turbulence kinetic energy budget (TKE budget) of said data. The output will present these parameters and produce plots such as contours in Tecplot formatting. The program is preliminary named KAHPTR, Kinetic energy Analysis with Heat flux Post-processing Turbulence and Reynolds.
Turbulence refers to the appearance of chaotic and unpredictable nature of fluid flow, which exists in all aspects of daily life. A definition by Hinze (1975) offered that "Turbulent fluid motion is an irregular condition of flow in which the various quantities show a random variation with time and space coordinates, so that statistically distinct average values can be discerned." Eddy motions are referred to most frequently and appear with a wide range of sizes and turbulent stresses. There exists inherited instability, non-linearity, continuum phenomenon, vortex stretching, energy cascades, and diffusivity with turbulence when visually representing them. In order to ascertain this 'chaotic' flow, statistical mechanics is utilized to simplify its intractability. A lot of research has been conducted with theoretical and computational models for predicting incompressible turbulent flow, however little consideration has been made towards hypersonic compressible turbulent flow with roughness. Compressible hypersonic roughness considerations is the main objective of the independent study.
The program utilizes C++ with CMake as a cross-platform build system generator; generating native build files for a specific platform. Then usually different build systems will be utilized to compile the C++ files for KAHPTR to be run. Either Make or Ninja will be used depending on user options and your OS defaults.
KAHPTR requires certain external dependencies in order to run locally. However, on CURC, it can be run without any additional installations. It only requires the GitHub repo to be installed locally on the remote environment.
To run locally on your machine, any operating system (Linux/MacOS/Windows/RedoxOS), you need access to the following systems for a C++ environment:
- Compiler: clang (clang++) / GNU (g++) / MSVC
- Assembler: compiler assembly into objects -> as / llvm-as
- Linker: Glue objects + libraries to executable -> ld.lld / ld
- C++ Standard Library (headers + runtime) -> libstdc++ / libc++
- C runtime & start files -> libc
- Archiver & Friends -> ar / ranlib/ nm
- Build driver -> CMake + Make/Ninja
The below terminal commands are just standard, it is highly reccomended to follow tuturials for your specific system. Visual Studio (cpp) provides a good foundation.
Linux(Debian)
sudo apt update
# GCC Stack -> GNU (native support)
sudo apt install -y build-essential cmake ninja-build gdb
# Clang + libc++ + lld + build tools -> LLVM
sudo apt install -y clang lld libc++-dev libc++abi-dev cmake ninja-build make gdbmacOS
# compilers + macOS SDK
xcode-select --install
# Optional newer LLVM & tools:
brew install llvm cmake ninja gdb
# Use Homebrew clang explicitly:
export CC=$(brew --prefix)/opt/llvm/bin/clang
export CXX=$(brew --prefix)/opt/llvm/bin/clang++Windows
# MSYS2/MinGW (GCC Stack)
pacman -S --needed base-devel mingw-w64-ucrt-x86_64-toolchain cmake ninjaIntrospection
clang++ --version
g++ --version
cmake --version
ninja --version
make --version
# See which linker/stdlib are used:
clang++ -v test.cpp -o test
# Show resource dir (where runtimes live):
clang++ -print-resource-dir
# Inspect linked libs on the binary:
ldd ./app # Linux
otool -L app # macOS
dumpbin /DEPENDENTS app.exe # Windows (VS tools)For the following commands, it is necessary to have git installed on your system. The utilization of an SSH key is reccomended and relevant documentation can be found with a simple search. Installing git is seperate from GitHub, it is a version control system for your operating system. A simple install on linux can be done as the following, other operating systems have been omitted:
Linux(Debian)
sudo apt update
sudo apt install gitGit Version Check
# You can utilize this command to ensure git is installed on all operating systems
git --versionThe simplest method of getting KAHPTR on your local machine or on CURC would be to clone the repository (make a local copy on that machine). You can utilize the following steps:
- Open a new terminal and navigate to a directory that you wish for KAHPTR to exist. You can use the commands:
- change directory: cd (.. / . / >FolderName<)
- list: ls (-l -a)
- print working directory: pwd
- make directory: mkdir (name)
- find file system: find / -name 'file name'
- Clone the repo - taking the local clone link from the green button on the main page (HTTP/SSH)
git clone https://github.com/github_user/repo.git
- Change git remote url to avoid accidental pushes to base project
git remote set-url origin github_username/repo_name git remote -v # confirm the changes
There are certain data processing techniques applied, which the user can select in the input file. The high level overview of all the methods are shown here and the actual implementation of the input file is shown in the Usage section. Furthermore, the general abstraction (hiding implementation details) towards just using KAHPTR is shown here. You can read the independent study to understand these methods in more detail, however, not necessary.
It is important to remember that the meshes that are given to US3D (CFD) have centroids. These points are defined for the finite-volume method for numerical discretization for element data; whereas, element faces evaluate fluxes. These are the points that ITKIT produces for your data slices.
KAHPTR can perform an operation of reducing a 2D slice to a 1D profile by averaging along the spanwise direction along the entire slice's wall normal profile. It is important to note that no disernable values can be considered as accurate, it instead allows for the analysis of trends. This is due to many of the variables being non-linear (product of terms mostly), while it takes a statistical mean (linear operation), hence there is linearization of non-linear terms. It does not follow the mathematical definition of linearity, which is defined under additivity + homogeneity.
Non-linear fluxes and sources do not average to the flux or source of the averaged field.
- ⟨ρ u u⟩ ≠ ⟨ρ u⟩ ⟨u⟩
- ⟨uᵢ uᵢ⟩ = ⟨uᵢ⟩ ⟨uᵢ⟩ + ⟨uᵢ′ uᵢ′⟩ → extra variance term
- ⟨p u⟩ = ⟨p⟩ ⟨u⟩ + ⟨p′ u′⟩
These covariance terms are physical (transport by fluctuations) and appear naturally, just as in Reynolds averaging.
- For uniform grid → use index-based averaging (exact correspondence).
- For non-uniform or misaligned grid → use binning (robust; can emit variance).
- Do not replace non-linear terms with the same function of averaged fields—keep the covariance/variance terms.
- What it does: takes the same point index across all spanwise lines and averages them.
- When to use: data are uniformly sampled in the span direction (same number/order of points per line) and aligned.
- Pros: very fast, deterministic; preserves exact correspondence point-by-point.
- Cons: sensitive to missing lines, jitter, or nonuniform spacing.
- What it does: groups spanwise coordinates into bins (by wall-normal) and averages values that fall in each bin.
- When to use: nonuniform spanwise spacing, missing points/lines, perodic mesh.
- Pros: robust to gaps.
- Cons: slightly slower; results depend on Freedris-Draconis bin definition (FDBinningFactor).
TL;DR — Span averaging is linear for sums but not for products or squares. Expect extra covariance terms (e.g. ⟨u v⟩ − ⟨u⟩ ⟨v⟩) in averaged equations and energy budgets — that’s the correct physics. If your data have slight misalignment across span lines, prefer binning. If they’re perfectly uniform and ordered, index-based is fastest and preserves exact correspondence.
A coordinate line represents a one-dimensional cut through the CFD slice. This is produced by a line at a specified constant spanwise location, along which we extract variables as functions of the wall-normal direction. When building coordinate lines, KAHPTR identifies all data points that lie near a target spanwise location according to a specified distance-scaled tolerance of a MAD (Mean Absolute Deivation) function.
It is important to note that the raw coordinate line extracted, if the tolerance was not tight enough, could extract multiple spanwise points at a specified wall-normal height. You can use the interpolated data file for coordinate lines to get the statistical average single ~vertical coordinate line.
All lines, spanwise or coordinate lines are interpolated. It utilizes the Thomas Cubic Spline Interpolation method. These files are given a 10x resolution and account for point overlap to avoid Runge phenomenon to the best of its ability.
Some turbulent quantities in KAHPTR require spatial gradients. It supports finite-difference gradients using neighboring gradient slices in the streamwise direction.
| Mode | Slices needed | Accuracy |
|---|---|---|
central |
both a backward slice at (x0−Δx) and a forward slice at (x0+Δx) | 2nd-order accurate; preferred |
forward |
a forward slice at (x0+Δx) | 1st-order |
backward |
a backward slice at (x0−Δx) | 1st-order |
none |
— | All gradient-dependent variables set to 0 |
- Prefer
centralwhenever you can supply both neighbor slices; it’s more accurate and less noisy. - At domain ends or when only one neighbor slice exists, choose
forwardorbackward.
TL;DR: Pick a gradient mode, provide the necessary neighbor slice(s). If requirements aren’t met, KAHPTR safely zeros those gradient-based terms.
The program outputs to root folder outside of the KAHPTR folder, generating a new folder with the outputted data files (.dat). An example of having 2 slices processed, it appears as the following:
KAHPTR_OUTPUT/ ├─ slice_1/ │ ├─ InterpolatedSliceFiles/ │ │ ├─ Cart_IntpCoordLine_line1.dat │ │ ├─ Cart_IntpCoordLine_line2.dat │ │ ├─ Cart_IntpSpanAvg.dat │ │ ├─ Cyl_IntpCoordLine_line1.dat │ │ ├─ Cyl_IntpCoordLine_line1.dat │ │ └─ Cyl_IntpSpanAvg.dat │ ├─ Cart_CoordLine_line1.dat │ ├─ Cart_CoordLine_line2.dat │ ├─ Cart_ITKIT_KAHPTR.dat │ ├─ Cart_SpanAvg.dat │ ├─ Cyl_CoordLine_line1.dat │ ├─ Cyl_CoordLine_line2.dat │ ├─ Cyl_ITKIT_KAHPTR.dat │ └─ Cyl_SpanAvg.dat └─ slice_2/ ├─ InterpolatedSliceFiles/ │ ├─ Cart_IntpCoordLine_line1.dat │ ├─ Cart_IntpCoordLine_line2.dat │ ├─ Cart_IntpSpanAvg.dat │ ├─ Cyl_IntpCoordLine_line1.dat │ ├─ Cyl_IntpCoordLine_line1.dat │ └─ Cyl_IntpSpanAvg.dat ├─ Cart_CoordLine_line1.dat ├─ Cart_CoordLine_line1.dat ├─ Cart_CoordLine_line2.dat ├─ Cart_ITKIT_KAHPTR.dat ├─ Cart_SpanAvg.dat ├─ Cyl_CoordLine_line1.dat ├─ Cyl_CoordLine_line2.dat ├─ Cyl_ITKIT_KAHPTR.dat └─ Cyl_SpanAvg.dat KAHPTR/ └─ ...
As seen above, it outputs cartesian slices as standard, and if the user specifies, it outputs cylindrical data files. The files names have been truncated to fit this README.
Note that most variables from ITKIT are primitive (mean variables). Favre-averaged variables must be computed and utilized, statistical mechanics, to generate the fluctuation variables. These are used for the variables being computed mostly. There are certain conventions that must be followed.
Each Cartesian slice contains all fundamental flow, thermodynamic, viscous, and turbulent-transport variables required for post-processing. These are written as tab-separated columns with the following names:
| Variable | Description |
|---|---|
sim_time |
Simulation time |
x, y, z |
Cartesian coordinates |
r, theta |
Cylindrical equivalents for radial and azimuthal position (set to zero for cartesian slice) |
| Variable | Description |
|---|---|
rho |
Density |
rhoU, rhoV, rhoW
|
Momentum components ( |
rhoT |
Energy (ρT) |
p, T
|
Static pressure and temperature |
div |
Flow divergence |
ox, oy, oz
|
Vorticity components |
| Variable | Description |
|---|---|
rhoUU, rhoVV, rhoWW
|
Normal Stresses ( |
rhoUV, rhoUW, rhoVW
|
Shear Stresses ( |
rhoTT |
Temperature variance ( |
rhoUT, rhoVT, rhoWT
|
Velocity-temperature covariances |
rhoRHO |
Density self-correlation ( |
pP |
Pressure variance |
| Variable | Description |
|---|---|
U, V, W
|
Velocity components |
residual |
Iterative solver residual |
mu, kap
|
Dynamic viscosity |
cp, cv
|
Specific heats |
h, rhoh
|
Enthalpy ( |
rhoUh, rhoVh, rhoWh
|
Enthalpy flux components ( |
| Variable | Description |
|---|---|
rhoU_UU_VV_WW, rhoV_UU_VV_WW, rhoW_UU_VV_WW
|
Mixed momentum sums ( |
pU, pV, pW
|
Pressure-velocity transport terms |
| Variable | Description |
|---|---|
tauXX, tauYY, tauZZ |
Normal stresses |
tauXY, tauXZ, tauYZ |
Shear stresses |
tauXXU_tauXYV_tauXZW, tauYXU_tauYYV_tauYZW, tauZXU_tauZYV_tauZZW |
Viscous work terms |
tauijDIV |
Divergence of viscous stress |
p_duk_dxk |
Pressure dilatation term |
| Variable | Description |
|---|---|
rhoKE |
Turbulent kinetic energy ( |
rhoTauUU, … , rhoTauWW
|
Reynolds Stresses |
q_T_x, q_T_y, q_T_z
|
Turbulent Heat Flux components |
q_L_x, q_L_y, q_L_z
|
Laminar Conductive Heat Flux components |
q_total_x, q_total_y, q_total_z
|
Total heat flux components (turbulent + laminar) |
| Variable | Description |
|---|---|
Conv |
Convection |
Prod |
Production |
TurbTrspt |
Turbulent transport |
Pwork |
Pressure work |
Ptrspt |
Pressure transport |
Pdil |
Pressure dilatation |
Diffusion |
Molecular diffusion |
Dissipation |
Viscous dissipation ( |
It follows the same convention as cartesian, except works in the cylindrical coordinate system. It defines instead variables of x-y-z as r-theta-z (where z is the specified spanwise coordinate). The variables say z, however, if the user specifies such as r-theta-y plane, with
⚠️ KAHPTR Version → If using a new version of KAHPTR, delete your current build/ directory and recompile the program. This is especially required if you’re using the provided.bator.shshortcut scripts. They only verify that a build directory exists, not that it is from a previous version.
🚨 ITKIT Version → Ensure that the version of ITKIT used matches the current version of KAHPTR. There are built-in checks to ensure variables match. However, to avoid having to re-simulate with US3D, ensure that the versions are compatible.
To avoid any issues with unfamiliarity with CMake or C++ generally, some .bat (Windows - Batch) and .sh (Unix - Shell) scripts exist in the root for ease of use.
You most likely must assign permissions to the executable/script (.bat / .sh), the following needs to be done:
# Unix System (Linux / macOS)
chmod +x <filename>.shThe input file is essential, defining the parameters and the outputs that the user wishes to extract from KAHPTR. The file must exist in the root with the name KAHPTRuser.inp. If an error occurs or you accidently delete the file, there is a file generator script to generate a new input file with some examples. Note that all fields must be filled, the input file checker will verify these parameters and tell you what it interpreted.
Below is a representative KAHPTRuser.inp layout for reference.
# KAHPTR INPUT FILE FORMAT - (USER self-identifying title)
# File Name Format: "KAHPTRuser.inp"
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
H# Total_Slices No.Variables FDbinningFactor NeighborPoints DistPower TanhBetaWN Slice_Directory_Location/NAME#
5 57 1.0 8 2 2.0 ../slices/stats/slice_stats#
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
H# Slice_Number Spanwise Wall_Normal Plane_Definition Number_of_Lines WN_origin Structured WN_points SP_points Total_points
1 x y N 2 7.62e-2 Y 300 108 32400
2:4 z r xy -1 7.62e-2 Y 300 108 32400
5 z y N N 7.62e-2 Y 300 108 32400
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
H# Slice_Number Line_Number Line_Extraction_Location(SP) Tolerance
1 1 -1.05252e-3 0.95
1 2 9.83662e-06 0.95
2:4 1 2.99e-4 0.98
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
H# Slice_Number Fwd_DiffSliceDirectory/NAME Bwd_DiffSliceDirectory/NAME WN_MinStep SP_MinStep GrowthRate <ab>Angle(deg)
1 ../diff/slice_stats009 ../diff/slice_stats011 2.74e-6 1.97e-5 1.90 30
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
To generate a new input file, or overwrite the current one, you can run the executable script in the root folder:
# Unix System (Linux / macOS)
./runKAHPTRinputfile.sh
# Windows
runKAHPTRinputfile.bat💡 Note: ! indicates reccomended
| Parameter | Description | Typical Values | Notes |
|---|---|---|---|
Total_Slices |
Total number of slices to be processed | Must match number of slice defined | |
No.Variables |
Number of variables in the slice files .dat | Must equal column count in .dat (1st version control check) | |
FDbinningFactor |
Freedris-Draconis binning fidelity factor for span-average line | 0.25-2.0 !(1.0) | Controls resolution of binning width (larger scale factor, larger bins) |
NeighborPoints |
Number of nearest neighbors for interpolation of unstructured grid for each undefined centroid | 8-32 !(8) | Larger is smoother interpolation, but takes more erroneous data |
DistPower |
Inverse Distance Weighting parameter | 1-3 !(2) | For NeighborPoints it defines the weighting of close vs. far points with power function |
TanhBetaWN |
Weighting factor for wall-normal interpolation bias function | 1.0-5.0 !(2.0) | Larger value = stronger wall emphasis, zero defines even spacing |
Slice_Directory_Location/NAME# |
Base directory of slice data | Path | KAHPTR appends Slice_Number automatically where # resides |
| Parameter | Description | Typical Values | Notes |
|---|---|---|---|
Slice_Number |
Slice IDs according to file name |
|
Can use colon operator to define multiple of same type |
Spanwise |
Slice Spanwise Direction Variable | Match coordinate convention ( |
|
Spanwise |
Slice Wall Normal Direction Variable | Match coordinate convention ( |
|
Plane_Defintion |
Coordinate Plane |
Use N for cartesian, theta defined by arctan(var2/var1) | |
Number_of_Lines |
Number of extracted lines ( |
Use N for none, 0 for only span-average, |
|
WN_origin |
Wall reference offset (wall normal origin) | Float | Used with TanhBetaWN
|
Structured |
Whether grid is structured (interpolate for contour) | Y/N | Y indicates not to interpolate grid |
WN_points |
Points in wall-normal direction of slice | Must match grid size (for tecplot) or if interpolating requested fidelity | |
SP_points |
Points in spanwise direction of slice | — | |
Total_points |
User verification of total points in slice (WN |
Used for validation |
| Parameter | Description | Typical Values | Notes |
|---|---|---|---|
Slice_Number |
Applies to which slice(s) |
|
Can use colon operator to define multiple of same type |
Line_Number |
Line index for output | Unique identifier to slice | |
Line_Extraction_Location(SP) |
Spanwise coordinate line location of extraction | float | Location depends on geometry of slice and requested location |
Tolerance |
Spanwise coordinate line inlier point search | float !(0.9-0.98) | 0-1; larger = tighter filtering according to MAD |
| Parameter | Description | Typical Values | Notes |
|---|---|---|---|
Slice_Number |
Applies to which slice | No use of colon operator to define multiple of same type | |
Fwd_DiffSliceDirectory/NAME |
Forward slice Directory & filename | path | Used for |
Bwd_DiffSliceDirectory/NAME |
Backward slice Directory & filename | path | Used for |
WN_MinStep |
Minimum |
float |
Most likely near wall, smallest spacing. Used for nearest neighbor radius searching. |
SP_MinStep |
Minimum |
float |
Most likely even spacing. Used for nearest neighbor radius searching. |
GrowthRate |
Geometric WN_MinStep & SP_MinStep growth rate |
float |
Nearest neighbor radius searching growth rate, attempts maximum of 10 times before terminating |
<ab>Angle(deg) |
Standard Vector Inner Product (dot product) angle in degrees |
|
Nearest neighbor filtering method, acts like a cone in direction of wanted derivative |
Once navigated to the KAHPTR root folder through the terminal, you can just run the script:
# Unix System (Linux / macOS)
./runKAHPTR.sh
# Windows
runKAHPTR.batIt runs the following commands:
# create build/ if it does not exist
if [ ! -d build ]; then
mkdir build
fi
# change directory to build/
cd build
# run cmake from givens in root
cmake ..
# build/compile files in cwd
cmake --build .
# install the executable (machine code) in cwd
cmake --install .
# change directory to root
cd ..
# run the program (machine code)
./KAHPTR_MAIN- Setup New GitHub Repo and release working version
- Re-write in the C programming language
- Enhanced Readability for future work
- Self-written Data Structures such as KD trees
- Addition of Turbulent Chemistry Analysis - renamed program to KAHPTR-C (C lang and Chem)
- Add test cases and examples (GitHub check as well)
- Utilize a wall-shear-stress model for relative boundary layer location
- Fix issues with gradients and cylindrical coordinates (TKE budget)
See the open issues for a full list of proposed features (and known issues).
Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated.
If you have a suggestion that would make this better, please fork the repo and create a pull request. You can also simply open an issue with the tag "enhancement". Don't forget to give the project a star! Thanks again!
- Fork the Project
- Create your Feature Branch (
git checkout -b feature/AmazingFeature) - Commit your Changes (
git commit -m 'Add some AmazingFeature') - Push to the Branch (
git push origin feature/AmazingFeature) - Open a Pull Request
Lead Contributer: Hans-Kristian Erik Östlund
Contact Information: haos8244@colorado.edu / hkristian.ostlund@gmail.com
Distributed under the GNU General Public License v3.0 (GPL-3.0). See LICENSE.txt for full terms.
TL;DR:
You are free to use, modify, and distribute this software — as long as derivative works remain open source under the GPL-3.0 license. Commercial use is allowed, however you must provide source code and retain license notices.
A sincere thank you to both Dr. Robyn Macdonald and Mateus Braga for their patience and mentorship in supporting my learning of the material and taking time out of their day to support this project.