Skip to content

Repository files navigation

Coated rotating cylinder in two dimensions

Direct numerical simulation infrastructure for the two-dimensional evolution of a liquid coating on a rotating cylinder. The implementation is based on Basilisk C and combines adaptive mesh refinement, volume-of-fluid interface tracking, two-phase Navier--Stokes dynamics, surface tension, gravity, automated parameter sweeps, performance profiling, and publication-oriented post-processing.

This repository is intended to provide a compact and reproducible computational companion to the associated study available at https://doi.org/10.1017/jfm.2020.421, bringing together mathematical modelling, asymptotic analysis, reduced-dimensional modelling calculations and direct numerical simulation towards resolving the delicate interplay between forces found in the (highly nonlinear) dynamics of a liquid film coating a rotating cylinder, inspired by the so-called honey dipper problem elegantly presented by H. K. Moffatt in 1977. It supports collaborative work with Dr. Alexander W. Wray at the University of Strathclyde, whom I am grateful to for bringing this problem to my attention back in 2018 and for fantastic discussions on this topic since then.

centre_of_mass_trajectory

Note

This implementation was built and adapted a posteriori, following an initial effort in Gerris in 2019, which underpinned the results in the publication itself. For more details on the original implementation, please refer to Appendix A.3 within the respective study. While some workflow details have been adapted, the overall structure and parametric setup was intentionally kept closely linked with the published contribution - see Figure 6(b) and Table 1 in particular as foundations for the example figure above and the broader configuration of the reference case in this repository itself.


πŸ“Œ Features

βœ… Two-dimensional incompressible two-phase Navier--Stokes solver
βœ… Volume-of-fluid representation of the liquid--gas interface
βœ… Surface tension, gravity, density contrast, and viscosity contrast
βœ… Rotating unit-radius cylinder with an initially prescribed coating thickness
βœ… Adaptive quadtree refinement with configurable maximum AMR level
βœ… Automated sweeps over film radius, rotation coefficient, and resolution
βœ… Centre-of-mass convergence criterion for automatic run termination
βœ… Persistent liquid-film rupture diagnostic based on connected components
βœ… Interface, diagnostic, snapshot, and animation output
βœ… Optional Basilisk TRACE and Linux perf profiling
βœ… Python post-processing for coating thickness and spatial trajectories
βœ… Reproducibility metadata, timing information, exit status, and source checksum


🌊 Physical and numerical model

The principal simulation is contained in CoatedCylinder.c. It models a liquid film coating the exterior of a rotating circular cylinder in a surrounding gas. The flow is solved using Basilisk's centred incompressible Navier--Stokes formulation together with volume-of-fluid interface tracking and surface tension.

The principal runtime parameters are:

  • film-radius parameter fRadius;
  • dimensionless cylinder-rotation coefficient cV;
  • maximum adaptive-mesh level MAX_LEVEL.

The cylinder radius is nondimensionalised to unity. The calculation uses adaptive quadtree refinement and tracks the liquid centre of mass, coating-thickness extrema, connected liquid components, and saved interfaces throughout the run.


πŸ› οΈ Installation

1. Requirements

The simulation workflow requires:

  • Basilisk C with qcc;
  • a C compiler with OpenMP support;
  • GNU make;
  • /usr/bin/time;
  • optional visualisation utilities such as ffmpeg, ImageMagick, and gnuplot;
  • optional Linux perf for hardware-counter profiling.

On a Debian/Ubuntu-like system, useful supporting packages include:

sudo apt install build-essential gnuplot imagemagick ffmpeg

2. Clone the repository

git clone https://github.com/rcsc-group/CoatedRotatingCylinder2D
cd CoatedRotatingCylinder2D

3. Install and configure Basilisk

Follow the official Basilisk installation instructions.

The supplied runner expects the BASILISK environment variable to point to the Basilisk source directory and qcc to be available on PATH. A typical setup is:

export BASILISK=$HOME/basilisk/src
export PATH=$PATH:$BASILISK

It is convenient to place these lines in ~/.bashrc or the equivalent startup file for your shell.


▢️ Running the simulations

Move to the driver-code directory:

cd DriverCode

Single case

A standard production run at maximum AMR level 10 can be launched with:

TRACE_LEVEL=0 \
USE_PERF=0 \
OMP_NUM_THREADS=4 \
MAX_LEVEL=10 \
sh run_cylinder.sh

Resolution study

Whitespace-separated values are interpreted as parameter lists:

TRACE_LEVEL=0 \
USE_PERF=0 \
OMP_NUM_THREADS=4 \
MAX_LEVEL="7 8 9 10 11" \
OUTROOT="output" \
sh run_cylinder_sweep.sh

The source is compiled once and one simulation is launched for each requested resolution.

General parameter sweep

The same mechanism applies to the film radius and cylinder velocity:

FRADIUS="1.25 1.5 1.75" \
CV="0.5 1.0" \
MAX_LEVEL="8 9 10" \
TRACE_LEVEL=0 \
USE_PERF=0 \
OMP_NUM_THREADS=4 \
OUTROOT="output" \
sh run_cylinder.sh

This executes the Cartesian product of all supplied values.

Each case is written to a directory of the form

fR_<fRadius>_cV_<cV>_L_<MAX_LEVEL>

for example:

fR_1.5_cV_1.0_L_10

βš™οΈ Execution and profiling controls

Variable Purpose Typical production value
FRADIUS Film-radius value or whitespace-separated sweep 1.5
CV Cylinder-rotation coefficient or sweep 1.0
MAX_LEVEL Maximum AMR level or sweep 10
OMP_NUM_THREADS Number of OpenMP threads machine/problem dependent
OUTROOT Root simulation-output directory output
TRACE_LEVEL Basilisk event/function tracing 0
USE_PERF Linux hardware-counter collection 0

For profiling runs:

TRACE_LEVEL=2 USE_PERF=auto sh run_cylinder.sh

For clean production timing:

TRACE_LEVEL=0 USE_PERF=0 sh run_cylinder.sh

USE_PERF=1 can be used when hardware counters are required and the run should fail rather than silently continue when perf is unavailable.

Note

OpenMP scaling is problem- and resolution-dependent. Small adaptive grids may not benefit from a large thread count. Benchmark representative cases before selecting the production value of OMP_NUM_THREADS.

Note

Compiler optimisation flags are configurable through the runner. If -march=native is enabled, compile the executable on a machine with the same CPU architecture as the machine on which it will run.


πŸ“ Repository structure

.
β”œβ”€β”€ CoatedCylinder.c
β”œβ”€β”€ run_cylinder.sh
β”œβ”€β”€ run_cylinder_sweep.sh
β”‚
β”œβ”€β”€ plot_com_trajectory.py
β”œβ”€β”€ plot_com_trajectory_resolution.py
β”œβ”€β”€ plot_thickness.py
β”œβ”€β”€ plot_thickness_resolution.py
β”œβ”€β”€ postprocess_common.py
β”‚
β”œβ”€β”€ output/
β”‚   └── fR_1.5_cV_1.0_L_10/
β”‚       └── ...
β”‚
β”œβ”€β”€ LICENSE
└── README.md

The repository is deliberately kept compact:

  • CoatedCylinder.c contains the Basilisk simulation.
  • run_cylinder.sh provides the standard single-case/benchmark workflow.
  • run_cylinder_sweep.sh manages parameter and resolution sweeps.
  • postprocess_common.py contains the shared Python analysis utilities.
  • plot_*.py scripts generate single-case and resolution-comparison figures.
  • output/ contains a representative simulation output using the same directory convention produced by the sweep workflow.

The files in this repository and their organisation represent a minimal working version of the implementation, which encompasses the necessary ingredients for reproducibility, as well as sample output (in the sense of only a subset of the files being uploaded while trying to strike the balance between the framework being informative and compact). Once familiarity with the codebase has been reached, the following structure for the codebase is recommended:

.
β”œβ”€β”€ DriverCode/
β”‚   β”œβ”€β”€ CoatedCylinder.c
β”‚   └── run_cylinder.sh
β”‚
β”œβ”€β”€ PostProcessing/
β”‚   β”œβ”€β”€ postprocess_common.py
β”‚   β”œβ”€β”€ plot_thickness.py
β”‚   β”œβ”€β”€ plot_thickness_resolution.py
β”‚   β”œβ”€β”€ plot_com_trajectory.py
β”‚   β”œβ”€β”€ plot_com_trajectory_resolution.py
β”‚   └── README.md
β”‚
β”œβ”€β”€ Figures/
β”‚   └── ...
β”‚
β”œβ”€β”€ SupplementaryMovies/
β”‚   └── ...
β”‚
β”œβ”€β”€ LICENSE
└── README.md

DriverCode/ contains the simulation and execution workflow. PostProcessing/ contains the reusable Python analysis suite. Figures/ and SupplementaryMovies/ are natural locations for representative visualisations or outward-facing material in general.


πŸ“Š Simulation output

A parameter sweep produces a top-level output directory containing the compiled executable, build metadata, a sweep summary, and one directory per parameter combination:

output/
β”œβ”€β”€ CoatedCylinder
β”œβ”€β”€ build-metadata.txt
β”œβ”€β”€ sweep-summary.tsv
β”‚
β”œβ”€β”€ fR_1.5_cV_1.0_L_9/
β”‚   β”œβ”€β”€ Animations/
β”‚   β”œβ”€β”€ Interfaces/
β”‚   β”œβ”€β”€ Slices/
β”‚   β”œβ”€β”€ logdroplets.dat
β”‚   β”œβ”€β”€ logstats.dat
β”‚   β”œβ”€β”€ logvol.dat
β”‚   β”œβ”€β”€ perfs
β”‚   β”œβ”€β”€ rupture.flag
β”‚   β”œβ”€β”€ stdout.log
β”‚   β”œβ”€β”€ stderr.log
β”‚   β”œβ”€β”€ time.txt
β”‚   β”œβ”€β”€ event-profile.txt
β”‚   β”œβ”€β”€ exit-status.txt
β”‚   └── metadata.txt
β”‚
└── fR_1.5_cV_1.0_L_10/
    └── ...

The most useful diagnostic outputs are:

  • logvol.dat β€” film-volume and minimum/maximum thickness diagnostics;
  • logdroplets.dat β€” connected-component and centre-of-mass diagnostics;
  • Interfaces/ β€” saved liquid-interface coordinates;
  • rupture.flag β€” persistent 0/1 indicator recording whether multiple connected liquid components were detected;
  • perfs β€” Basilisk performance history;
  • time.txt β€” GNU time -v resource summary;
  • event-profile.txt β€” Basilisk TRACE=2 profile when enabled;
  • metadata.txt β€” case-level parameters and execution settings;
  • exit-status.txt β€” simulation process exit status.

At sweep level, sweep-summary.tsv provides a compact overview of the parameter combination, exit status, and rupture classification for each case.


🐍 Post-processing

The Python suite reconstructs coating-thickness histories, centre-of-mass trajectories, tracked maximum-thickness trajectories, final liquid interfaces, and resolution comparisons.

Python environment

From the PostProcessing/ directory, create a local virtual environment:

python3 -m venv .venv
. .venv/bin/activate

Install the required Python packages:

python3 -m pip install --upgrade pip
python3 -m pip install numpy matplotlib pylustrator

The environment only needs to be created once. In later sessions:

. .venv/bin/activate

To leave it:

deactivate

Standard plotting commands

For a single resolution:

python3 plot_thickness.py --level 10
python3 plot_com_trajectory.py --level 10

For a resolution study:

python3 plot_thickness_resolution.py --levels 7 8 9 10 11
python3 plot_com_trajectory_resolution.py --levels 7 8 9 10 11

A different simulation root can be supplied explicitly:

python3 plot_thickness_resolution.py \
  --output-root /path/to/output \
  --levels 7 8 9 10 11

For non-interactive execution:

python3 plot_thickness.py --level 10 --save-only

If external LaTeX rendering is unavailable:

python3 plot_thickness.py --level 10 --save-only --no-tex

The plotting scripts export publication-quality PDF files together with high-resolution PNG versions.


πŸ”¬ Reproducibility and performance information

The execution workflow records the numerical case parameters together with compiler, OpenMP, tracing, timing, and source-version information. Useful metadata include:

  • compiler and optimisation flags;
  • OpenMP thread count and placement settings;
  • requested parameter sweep;
  • source SHA-256 checksum;
  • tracing and hardware-counter configuration.

Performance measurements should distinguish between:

  • production timing β€” TRACE_LEVEL=0, USE_PERF=0;
  • Basilisk hotspot profiling β€” TRACE_LEVEL=2;
  • hardware-counter profiling β€” USE_PERF=1.

Instrumentation can affect runtime, so profiling and clean timing results should not be treated as directly interchangeable.


πŸ“š Citation

If you use this code or associated data in your work, please cite the accompanying publication:

Wray, A. W., & Cimpeanu, R. (2020). Reduced-order modelling of thick inertial flows around rotating cylinders. Journal of Fluid Mechanics, 898, A1.

BibTeX:

@article{wray2020reduced,
  title={Reduced-order modelling of thick inertial flows around rotating cylinders},
  author={Wray, Alexander W and Cimpeanu, Radu},
  journal={Journal of Fluid Mechanics},
  volume={898},
  pages={A1},
  year={2020},
  publisher={Cambridge University Press}
}

🀝 Contributing

Contributions and reproducibility feedback are welcome. Please feel free to:

  • open an issue for bugs, portability problems, or questions;
  • fork the repository;
  • submit a pull request for a well-tested improvement.

For numerical changes, please document any modifications to solver tolerances, mesh-adaptation criteria, physical parameters, compiler settings, or stopping conditions that may affect reproducibility.


About

Open-source software repository (based on Basilisk C) for the simulation of liquid film flow dynamics around rotating cylinders, supporting collaborative work with Dr. Alex Wray at the University of Strathclyde. Complements the open access publication available at https://doi.org/10.1017/jfm.2020.421.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages