"""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()