codexwingtip-vortex-pair.py
wingtip-vortex-pair.py
"""Constructed instantaneous cross-flow of a finite-core trailing-vortex pair.
Python 3.14 with NumPy/Matplotlib; see pyproject.toml. Writes PNG to cwd.
The two Rankine-style cores regularize the velocity; this is an illustrative
superposed velocity field, not an aircraft wake prediction or measured data.
"""
from pathlib import Path
import numpy as np
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
def velocity(y, z, separation=10.0, circulation=20.0, core_radius=0.4):
vy = np.zeros_like(y, dtype=float)
vz = np.zeros_like(z, dtype=float)
for center, strength in [(-separation / 2, -circulation), (separation / 2, circulation)]:
dy = y - center
radius_squared = np.maximum(dy**2 + z**2, core_radius**2)
coefficient = strength / (2 * np.pi * radius_squared)
vy -= coefficient * z
vz += coefficient * dy
return vy, vz
def main():
y = np.linspace(-10, 10, 241)
z = np.linspace(-5.8, 5.8, 161)
yy, zz = np.meshgrid(y, z)
vy, vz = velocity(yy, zz)
fig, axis = plt.subplots(figsize=(9, 4.7), dpi=120, layout='constrained')
fig.patch.set_facecolor('white')
background = axis.pcolormesh(yy, zz, vz, cmap='RdBu_r', vmin=-2, vmax=2,
shading='auto', rasterized=True)
axis.streamplot(y, z, vy, vz, color='#333333', density=1.3, linewidth=0.65,
arrowsize=0.8)
for center, label in [(-5, r'$-\Gamma$'), (5, r'$+\Gamma$')]:
axis.add_patch(plt.Circle((center, 0), 0.4, facecolor='white', edgecolor='black', zorder=4))
axis.text(center, 0, label, ha='center', va='center', fontsize=9, zorder=5)
axis.annotate('Downwash between the cores', xy=(0, -0.8), xytext=(-2.5, 4.1),
bbox={'facecolor': 'white', 'alpha': 0.9, 'edgecolor': 'none'},
arrowprops={'arrowstyle': '->', 'color': 'black'}, fontsize=9)
axis.set(xlabel='Spanwise coordinate y (m)', ylabel='Vertical coordinate z (m)',
title='Illustrative counter-rotating trailing-vortex pair', aspect='equal',
xlim=(-10, 10), ylim=(-5.8, 5.8))
fig.colorbar(background, ax=axis, label='Vertical velocity (m/s), clipped color scale', shrink=0.9)
fig.savefig(Path('wingtip-vortex-pair.png'), facecolor='white', transparent=False)
plt.close(fig)
if __name__ == '__main__':
main()