Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions docs/docs/api/firedrake/envs/cylinder/flow.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,3 +87,6 @@ Velocity vector for boundary condition
Blowing/suction actuation on the cylinder wall, following Rabault, et al (2018)
https://arxiv.org/abs/1808.07664

The two jets act as a zero-net-mass-flux pair: a positive control blows
through the upper jet and sucks through the lower jet with equal flow rate.

2 changes: 1 addition & 1 deletion docs/docs/examples/firedrake/cylinder.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ All scripts live in [`examples/firedrake/advanced/cylinder/`](https://github.com

Two independent actuation mechanisms are available:

- **Jet blowing/suction** ([`Cylinder`](../../api/firedrake/envs/cylinder/flow)): two 10° tangential jets at ±90° from the stagnation point — used by `solve-steady.py`, `unsteady.py`, `step_input.py`, and `pressure-probes.py`.
- **Jet blowing/suction** ([`Cylinder`](../../api/firedrake/envs/cylinder/flow)): two 10° jets at ±90° from the stagnation point with zero net mass flux — used by `solve-steady.py`, `unsteady.py`, `step_input.py`, and `pressure-probes.py`.
- **Rotary control** ([`RotaryCylinder`](../../api/firedrake/envs/cylinder/flow)): 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.
Expand Down
7 changes: 5 additions & 2 deletions hydrogym/firedrake/envs/cylinder/flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,9 @@ def cyl_velocity_field(self):

Blowing/suction actuation on the cylinder wall, following Rabault, et al (2018)
https://arxiv.org/abs/1808.07664

The two jets act as a zero-net-mass-flux pair: a positive control blows
through the upper jet and sucks through the lower jet with equal flow rate.
"""

# Set up tangential boundaries to cylinder
Expand All @@ -217,5 +220,5 @@ def cyl_velocity_field(self):
0.0,
)

# Normal velocity (blowing/suction) at the cylinder wall
return ufl.as_tensor((self.x, self.y)) * (A_up + A_lo)
# Normal velocity at the cylinder wall (blowing on top, suction on bottom)
return ufl.as_tensor((self.x, self.y)) * (A_up - A_lo)
12 changes: 12 additions & 0 deletions test/test_cyl.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,18 @@ def test_steady(tol=1e-3):
assert abs(CD - 1.2840) < tol # Re = 100


def test_jet_zero_net_mass_flux(tol=1e-8):
flow = hgym.Cylinder(mesh="medium")

# Volume flux from the cylinder wall into the fluid for unit actuation
flux = fd.dot(flow.cyl_velocity_field, -flow.n)
upper_flux = fd.assemble(fd.conditional(flow.y > 0, flux, 0.0) * fd.ds(flow.CYLINDER))
lower_flux = fd.assemble(fd.conditional(flow.y < 0, flux, 0.0) * fd.ds(flow.CYLINDER))

assert upper_flux > 0 # Blowing through the upper jet
assert abs(upper_flux + lower_flux) < tol * abs(upper_flux)


def test_steady_rotation(tol=1e-3):
Tf = 4.0
dt = 0.1
Expand Down
Loading