Skip to main content

Cylinder

Advanced workflow examples

The scripts on this page access the Firedrake solver directly — they do not use the standard env.reset() / env.step() interface. For RL training, see Getting Started.

Flow past a circular cylinder is the canonical benchmark for flow instability and active flow control. At Re = 100 the steady symmetric flow bifurcates via a supercritical Hopf bifurcation, and the wake develops into a periodic von Kármán vortex street. This makes the cylinder an ideal test case for studying the transition mechanism, validating control strategies, and benchmarking RL agents.

All scripts live in examples/firedrake/advanced/cylinder/.

Physical setup

  • Geometry: circular cylinder of radius 0.5 in a 2-D domain
  • Inflow: uniform velocity U∞ = 1.0 from the left boundary
  • Reynolds number: Re = 100 (default)

Two independent actuation mechanisms are available:

  • Jet blowing/suction (Cylinder): two 10° tangential jets at ±90° from the stagnation point — used by solve-steady.py, unsteady.py, step_input.py, and pressure-probes.py.
  • Rotary control (RotaryCylinder): a prescribed tangential surface velocity — used by run-transient.py, pd-control.py, pd-phase-sweep.py, and lti_system.py.

Both mechanisms are capable of suppressing vortex shedding, but they operate through different physical mechanisms and are suited to different control design approaches.

Workflow overview

Step 1 — Observe natural vortex shedding

Run the uncontrolled cylinder flow to generate a time-periodic reference trajectory and a restart checkpoint for subsequent steps:

python run-transient.py

Source: run-transient.py

The console prints the CL/CD time series; checkpoints are written for use in pd-control.py and related scripts.

Step 2 — Compute the unstable steady state

At Re = 100 the symmetric, non-shedding equilibrium exists but is unstable. It can be computed with a Newton solver and used as the base flow for stability analysis and LTI modelling:

python solve-steady.py

Source: solve-steady.py

Outputs: output/cylinder_Re100_steady.h5 and associated Paraview files.

Step 3 — Observe the transition to vortex shedding

unsteady.py chains the Newton solver and a transient simulation into a single run, demonstrating how a small perturbation to the steady state grows into the limit cycle:

python unsteady.py

Source: unsteady.py

  • Stage 1: Newton solve → unstable equilibrium
  • Stage 2: Perturbed transient integration → limit cycle

Step 4 — Linear stability analysis

Extract the leading eigenvalue (growth rate and shedding frequency) from the linearised Navier-Stokes operator around the steady base flow:

python stability.py

Source: stability.py

The script computes both direct and adjoint global modes via Arnoldi iteration. The optional checkpoint from solve-steady.py can be supplied to skip the internal steady solve.

Step 5 — Apply PD feedback control

With a vortex-shedding trajectory available, demonstrate open-loop-to-closed-loop switching with a proportional-derivative controller:

python pd-control.py

Source: pd-control.py

Prerequisite: a checkpoint produced by run-transient.py.

The script runs the flow uncontrolled for an initial period, then activates the PD controller and shows the oscillations decaying over time.

Complete script reference

ScriptPurposeKey featuresPrerequisites
solve-steady.pyCompute steady-state base flowNewton solver, Reynolds rampingNone
unsteady.pySteady → unsteady transitionTwo-stage: Newton + transientNone
run-transient.pyBasic time integrationSimple vortex-shedding demoNone
stability.pyLinear stability analysisEigenvalues, eigenmodes (direct/adjoint)Optional steady checkpoint
step_input.pySystem identificationStep-response for control designNone
pressure-probes.pyPoint measurementsSparse sensing at pressure probesNone
pd-control.pyFeedback controlPD controller with on/off phasesCheckpoint from run-transient.py
pd-phase-sweep.pyController tuningSweeps phase angles for optimal gainCheckpoint from run-transient.py
lti_system.pyLTI model extractionBase flow + actuation influence matrixNone

MPI parallelisation

All scripts support MPI-parallel execution:

mpirun -np 4 python run-transient.py
mpirun -np 4 python solve-steady.py
mpirun -np 4 python stability.py
mpirun -np 4 python pd-control.py