# LES of Channel flow with OpenFOAM

## Introduction

This repository contains OpenFOAM v2306 case setup files and results for channel
flow at $Re_\tau = 1000$.

It accompanies the following publication in the OpenFOAM Journal:
[https://doi.org/10.51560/ofj.v6.159](https://doi.org/10.51560/ofj.v6.159).
Kindly, cite the paper if you use the data in your research.

## Directory structure

- `M1`, `M2`, `M3` contain base implicit LES case setups and results on three
  increasingly fine grids.
- `M1_rk`, `M2_rk` are RKSymFOAM versions of the M1 and M2 cases.
- `M1_sigma`, `M2_sigma` run the Sigma LES model on the M1 and M2 grids using
  `pimpleFoam`.
- `M1_rk_sigma` runs the Sigma LES model on the M1 grid using RKSymFOAM.
- `M1_diffusive` uses LUST for the convection scheme.
- `M1_cfl01` and `M1_cfl02` contain additional simulations on the M1 grid with
  the target CFL number set to 0.1 and 0.2, respectively. Only results are
  provided; the setup matches `M1` except for the `maxCo` value in
  `system/controlDict`.
- `re180_simulations` collects additional simulations at Re_tau = 180:
  - `M1_re180`, implicit LES.
  - `M1_re180_sigma`, LES with the Sigma model.
  - `M1_re180_smag`, LES with the Smagorinsky model.
- `analysis_scripts` contains Python scripts that can be used to generate the
  figures found in the paper and compute quantities from collected probe data.
  See `analysis_scripts/README.md` for a script-by-script overview.
- `dns` contains a bash script for downloading the DNS data by Lee and Moser
  (2015). If the script is not executable after downloading it, you can use the
  `chmod` utility to set appropriate execution rights. The paper also makes use
  of another DNS dataset for skewness and flatness, obtained by us through
  private communication with P. Schlatter and S. Toosi at FAU, Germany. As
  such, we are not at liberty to share it publicly.
- `figures` contains a subdirectory, `from_paper`, containing all 24 figures
  used in OpenFOAM Journal article. This folder also serves as the default
  output for the scripts in the `analysis_scripts` folder.

## Software

All the results were generated using OpenFOAM v2306.

Additional software

- The following is necessary to run `pimpleFoam` cases, so it is mandatory to
  install.
  - [swak4Foam](https://sourceforge.net/p/openfoam-extend/swak4Foam) A large
    toolkit for OpenFOAM. In this project only `funkySetFields` is used, to set
    the initial conditions. If you use a different way of initialization, you
    can skip this.
  - [runTimeChannelBudgets](https://github.com/janneshopman/runTimeChannelBudgets)
    Tool for computing TKE budget terms.
  - [postChannelFlow](https://github.com/timofeymukha/postChannelFlow) Tool for
    averaging the averaged fields across x and z. You can use the built-in
    `postChannel`, but that will average only a hardcoded subset of the fields.
- The following are not needed to run `pimpleFoam` cases.
  - [RKSymFOAM](https://github.com/janneshopman/RKSymFoam) Low-dissipation
    solver with Runge-Kutta time steppers. Needed for running the `_rk` cases
    only.
  - [ofreaders](https://gitlab.com/chalmers-marine-technology/ofreaders/) Tool
    for handling various OpenFOAM-generated files in Python. Here used for
    converting probe data to HDF5. Not needed unless you want to perform this
    conversion.
  - Python packages: `numpy`, `matplotlib`, `scipy`, `h5py`, `tqdm`,
    `ofreaders`. Used in the provided analysis scripts to plot figures. A
    `requirements.txt` file is provided under `analysis_scripts` for
    convenience, see also the README.md in that folder.

## Running the cases

A typical Allrun file is provided below, heavily commented to aid the user. As
the cases are large, typically they would be run on a supercomputer, and a naive
Allrun script would not be used. Therefore, the script is provided more as a
demonstration of all the necessary steps to run the case.

```
#!/bin/sh

# This script is setup to run in serial for demonstration purposes.
# A realistic scenario is that you are running this on a cluster.
# In this case, run
# decomposePar
# after constructing the grid and run funkySetFields and the solver
# in parallel.
# After the solver is done, run
# reconstructPar -latestTime
# The paths in the rm command below have to also be adjusted.

# Copy dummy initial conditions
cp -r 0.org 0

# Generate the grid
blockMesh

# Run
# decomposePar
# here if running in parallel

# You can additionally run
# renumberMesh
# to make its numbering better suited for the simulations, resulting in some
# speedup

# Generate initial conditions
funkySetFields -time 0

# Run the solver. It will stop at time 250, which corresponds to the
# initial transient. You may want to make an initial investigation of
# the results at this point, to check for any obvious issues. There
# should not be any, but this is just good practice in general.
pimpleFoam

# Remove the mean fields to restart the averages. This way new averages
# will not be contaminated by the initial transient.
rm 250/*Mean
rm -r 250/uniform

# Change the endTime in the controlDict to 750 and run the solver again.
pimpleFoam

# Run
# reconstructPar
# here if running in parallel

# Average fields in xz
postChannelFlow -latestTime

# Compute the TKE budgets
channelBudgets -latestTime
```

An additional comment is necessary regarding the `re180_*` cases. In our work,
we initialized them by mapping the solution from the Re_tau 1000 data, using
`mapFields`.
```
mapFields -consistent ../M1 -sourceTime 750
```
This ensures transition (which is difficult at a low Re number), but leads to a
long transient. In the provided case setups the `funkySetFieldsDict` was
adjusted in the `re180_*` cases to match the DNS data for y^+, but we never
tested whether the case will transition.

## Data for each case

For each of the cases `M1`, `M2` and `M3`, the following is provided.

- A dummy `0.org` directory with constant initial conditions.
- A `constant` directory, with no grid.
- A `system` directory with all the necessary configuration files, including a
  `blockMeshDict` to generate the grid.
- A `postProcessing` directory with subdirectory `collapsedFields` containing
  the statistics at the latest time and (for selected cases) subdirectory
  `averageYPlus` containing the development of spatially-averaged $y^+$ in time.
- A `graphs` directory containing the profiles of the TKE budget terms.
- A `plane_stats.txt` file containing single-point statistics computed using
  probe data. These can be compared to those in the `postProcessing` directory.
  The columns in the file are in the following order:
  `<u>`, `<u'u'>`, `<v'v'>`, `<w'w'>`, `S_u`, `S_v`, `S_w`, `F_u`, `F_v`, `F_w`.
  Each row corresponds to a wall-normal location, increasing from the first
  off-wall cell toward the center of the channel.
- `z_spectrum_*.txt` files containing the spanwise spectra for each wall-normal
  value.
- `coherence_*.txt` files containing the linear coherence spectra with respect
  to $y^+ = 2$.
- `z_tpcorr_*.txt` files containing the two-point correlations of velocity in
  the spanwise direction for each wall-normal location.

For the remaining cases, probe data has not been collected, so the corresponding
results are not present (`plane_stats.txt`, `z_spectrum_*.txt`,
`coherence_*.txt`). Also, the `averageYPlus` data is not included. Finally,
to save space for cases `M1_cfl01` and `M1_cfl02` we only provide the results
and not the case setup files. The setup is identical to `M1`, except for the
value of the `maxCo` keyword in the `controlDict`.


## Probe data
Due to the size of the produced probe data files (> 100 Gb for the M3 case) we
are unable to easily share them. The data is available upon request. However, we
provide a portion of the data for the M1 grid via the following links. In these
files only every 4th time-step is retained.

[streamwise component](https://zenodo.org/records/18646720/files/probes_u_reduced.hdf5?download=1)

[wall-normal component](https://zenodo.org/records/18646720/files/probes_v_reduced.hdf5?download=1)

[spanwise component](https://zenodo.org/records/18646720/files/probes_w_reduced.hdf5?download=1)
